I'm trying to create an "Endless runner" game, where the player remains stationary on the origin of the axes while the tiles scroll with a fixed speed on the Z-Axis as they are instantiated. The script attached spawns 5 tiles at the start while already scrolling at the speed set in the GameManager and then keeps on spawning tiles based on a fixed spawning rate.
The problem I'm facing is calculating the correct distance between the tiles after the first five are instantiated so that each end of a tile is overlapped.
I'm attaching what I've written so far, in the TileManager script, in the hope that someone knows how to proceed, or perhaps knows a different method. Thanks!
public class TileManager : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private GameObject[] tilesArray;
[SerializeField] private int tilesToSpawn = 5;
[SerializeField] private float zPosSpawn = 0f;
[SerializeField] private float tileLength = 20f;
[SerializeField] private float scrollCoefficient;
private float timeSinceLastSpawned;
private float spawnRate;
void Start()
{
//scrollingObjectsSpeed = -1,5f
spawnRate = GameManager.Instance.scrollingObjectsSpeed * -1;
SpawnLogic();
}
void Update()
{
timeSinceLastSpawned += Time.deltaTime;
if (timeSinceLastSpawned >= spawnRate)
{
timeSinceLastSpawned = 0;
SpawnTiles(Random.Range(1, tilesArray.Length));
}
}
private void SpawnLogic()
{
for (int i = 0; i < tilesToSpawn; i++)
{
if (i == 0)
{
SpawnTiles(0);
}
else
{
SpawnTiles(Random.Range(0, tilesArray.Length));
}
}
}
private void SpawnTiles(int tileIndex)
{
scrollCoefficient = (GameManager.Instance.scrollingObjectsSpeed * -1f) * spawnRate ;
Instantiate(tilesArray[tileIndex], transform.forward * zPosSpawn, Quaternion.identity);
zPosSpawn = (zPosSpawn + tileLength) - scrollCoefficient;
}
}
`
I had the same issue with a previous game and I will suggest to you the best way to solve this.
create a list of GameObjects to save your tiles.
List<GameObject> tiles;
save your tiles in the list
tiles.Add((GameObject)Instantiate(tilesArray[tileIndex], transform.forward * zPosSpawn, Quaternion.identity);
check every tile to see its position
for(int i = 0; i < tiles.Count; i++)
{
if(grids[i].transform.position.z <= lowerPosition)
{
DestroyObject(tiles[i]);
tiles.Add((GameObject)Instantiate(tilesArray[tileIndex], transform.forward * zPosSpawn, Quaternion.identity);
}
}
DestroyObject() is just a simple function, but remember to remove the grid:
void DestroyObject(GameObject tile)
{
Destroy(grid);
tiles.remove(tile);
}
Hope it is useful!