using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Assertions.Must; using UnityEngine.Serialization; using Random = UnityEngine.Random; namespace TrafficSimulation{ public class CarPool : MonoBehaviour { public TrafficSystem trafficSystem; public static CarPool SharedInstance; public List carModels; public List pooledCars; public int poolSize; public float standardRayLength = 5; public bool randomizeRayLength = false; public float rayRandomizeRange = 4; public Camera bikeCam; public float spawnPositionCorrectionY; private void Awake() { SharedInstance = this; pooledCars = new List(); GameObject tmpInstance; for(int i = 0; i < poolSize; i++){ tmpInstance = Instantiate(carModels[Random.Range (0, carModels.Count)]); VehicleAI vAI = tmpInstance.GetComponent(); if(vAI == null){ Debug.Log("Carmodel has no AI. Destorying Instance!"); Destroy(tmpInstance); continue; } vAI.trafficSystem = this.trafficSystem; vAI.raycastLength = standardRayLength; CarSitter carSitter = tmpInstance.GetComponent(); if(carSitter != null){ carSitter.carPool = this; } tmpInstance.SetActive(false); pooledCars.Add(tmpInstance); } } public GameObject GetCar(){ foreach(GameObject car in pooledCars){ if(!car.activeInHierarchy){ return car; } } Debug.Log("no car free to use. returning null!"); return null; } public GameObject SpawnCar(Transform spawnTranform){ Vector3 carPosition = spawnTranform.position; if (spawnPositionCorrectionY != 0f) { carPosition = new Vector3(carPosition.x, carPosition.y + spawnPositionCorrectionY, carPosition.z); } return SpawnCar(carPosition, spawnTranform.rotation, null); } public GameObject SpawnCar(Vector3 spawnPos, Quaternion spawnRot, Transform lookAt) { GameObject car = this.GetCar(); if (car == null) { Debug.Log("No car was available. Spawn aborted"); return null; } PrepareCarToSpawn(car, spawnPos, spawnRot, lookAt); return car; } public void DespawnCar(GameObject car) { Plane[] planes = GeometryUtility.CalculateFrustumPlanes(bikeCam); Collider carCollider = car.GetComponent(); if (GeometryUtility.TestPlanesAABB(planes, carCollider.bounds)) { Debug.Log("Car in Cam, prospone the despawn!"); StartCoroutine(ProsponeDespawn(car, 1.0f)); return; } Debug.Log("Despawn Car!"); car.SetActive(false); } IEnumerator ProsponeDespawn(GameObject car,float time) { yield return new WaitForSeconds(time); DespawnCar(car); } private void PrepareCarToSpawn(GameObject car,Vector3 position, Quaternion rotation,Transform lookAt) { //Position + Rotation + Lookat car.transform.position = position; car.transform.rotation = rotation; if(lookAt != null) { car.transform.LookAt(lookAt); } //Status correction. Necessary when the car was despawned while in intersection VehicleAI ai = car.GetComponent(); ai.vehicleStatus = Status.GO; //If given, randomize RaycastLength if (this.randomizeRayLength) { ai.raycastLength = Random.Range(this.standardRayLength - this.rayRandomizeRange, this.standardRayLength + rayRandomizeRange); } car.SetActive(true); } } }