I am creating an endless runner game so I need there to be somewhere far up ahead there is an object with just a script that instantiates a road every 10 seconds, like this:
IEnumerator InstantiateRoad()
{
while (true) {
Instantiate(roadPrefab, new Vector3(transform.position.x, -0.25f, transform.position.z), Quaternion.identity);
yield return new WaitForSecondsRealtime(timeBetween);
}
}
The roadPrefab
shown above has a script on it that makes it move continuously like this:
void Update()
{
transform.Translate(Vector3.back * Time.deltaTime * speed);
}
However, this does not do the job smoothly since sometimes there is a very tiny space between blocks of road and sometime there is not a space. How can I fix this?
One thing to consider with your current approach is that the exact time a coroutine is run is not always consistent. Basically, if you say to Unity, WaitForSecondsRealtime(5), it’s only going to run if those 5 seconds have lapsed, not if it gets close, so think of it more as “WaitForAtLeastSecondsRealtime()”. That is to say, it will try to run as close to 5 seconds as possible, but it may be a little after that by the time it actually gets called.
One solution would be to determine where to place your next road (eg, the desired spacing between segments), and place them slightly in advance of when they’re needed to give yourself some buffer.
As a side note: You might also want to look at object pooling, as Instantiate can be expensive when called in the middle of the game loop. Periodically removing old segments, putting them back in the pool, and then placing them at the end again can help keep things memory friendly and prevent stuttering/frame drops.