if you have pro, you have Occlusion culling which means what is out of view is not render.
If you do not have it, then you can cut your track in mini parts, load them into an array and deactivate them all except the first and second ones.
Then you place trigger boxes (or check for distance) and when entering the box you deactivate the one behind and activate the one in front. In the end you always have only two parts active at a time.
Those portions of track could also include the AI cars, the ones just driving but not racing.
EDIT: Since your camera is not moving, let’s see another approach.
Each portion of track is under an empty gameObject and all those empty GO are under a main empty GO. This contains the track and a script to generate cars.
All cars are generated on start and placed in a pool of objects so that you do not have to instantiate and destroy them, you simply activate/deactivate. This happens in the start.
Also in the start, all portion object are placed in a dictionary. For instance if your portions are 20 units long then it means the first is at 0, second at 20 and so on. The position is the key and the object is the value.
public Transform mainTrackObject;
Dictionary<int, GameObject> dict = new Dictionary<int, GameObject>();
void Start()
{
foreach(Transform t in mainTrackObject){
int key = Mathf.RoundToInt(t.position.z);
dict.Add(key,t.gameObject);
t.gameObject.SetActive(false);
}
dict[0].SetActive(true);
}
Thanks to this you can “track” how much distance the car have done (even though it is not moving) and activate the portion.
float distance;
void Update(){
distance += Time.deltaTime * velocity; // Velocity is the assumed speed of the car
int dist = Mathf.RoundToInt(distance);
if(dist%20 == 0){
SetActivation.SetActive(dist);
}
}
void SetActivation(int key){
GameObject o = dict[key];
o.SetActive(true);
dict[dist - 20].SetActive(false)
// Get AI component for cars and call init method
o.GetComponent<CarAI>().Init();
}
If speed is constant, it is even more simple, you can simply do the activation/deactivation based on time using InvokeRepeating.
Concerning CarAI is could be a simple script with how many car and then place them on the road:
public int amountCar;
void Init(){
for(int i = 0; i < amountCar;i++){
GameObject car = PoolSystem.Pop();
car.SetActive(true);
// Position system, either random
// using SphereCast to detect if an object is already there
// or using an stack of predefined position on track
}
}
Concerning the stack pooling system I leave to you as you can find this on the internet.
THIS IS JUST GIVING YOU IDEAS, TAKING THE CODE AS IS MAY NOT WORK RIGHT AWAY, YOU MAY NEED TO TWEAK A LITTLE.