Search code examples
c#unity-game-engineinfinite-loopobjectinstantiation

How to instantiate a tile on the end of another moving tile?


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;
    }
}
`

Solution

  • I had the same issue with a previous game and I will suggest to you the best way to solve this.

    1

    create a list of GameObjects to save your tiles.

    List<GameObject> tiles;
    

    2

    save your tiles in the list

    tiles.Add((GameObject)Instantiate(tilesArray[tileIndex], transform.forward * zPosSpawn, Quaternion.identity);
    

    3

    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!