Infinite Runner - Object Pooling with diferente objects

Hi everyone!
I been working in a infinite runner for mobile and I recently I implement the method of object pooling to increase the perfomance and it really works great!.

My character has a Trigger who when in enter in the obstacle, spawn randomly a new obstacle in front of character. The problem is that object pooling first instantiate 6 object for every obstacles and when the trigger collide with the obstacles behind the character, spawn new object but sometimes disapear the object in front of character because he need to desactivate that object and respawn it in a new position.

There around 5 diferent prefabs for obstacles and randomly select the object to respawn.

This is my code for spawn obstacles:

using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class Pooling_ObstacleGenerationCollider : MonoBehaviour
{


    // Prefabs objects
    [Header("FloorLamps Obstacles")]
    public GameObject FloorLamp_Prefab;
    [Space(10)]

    [Header("Rocks Obstacles")]
    public GameObject Rock_Prefab;
    public GameObject Rock_PrefabB;
    public GameObject Rock_PrefabC;
    [Space(10)]

    [Header("Woods Obstacles")]
    public GameObject WoodObstacle_Prefab;
    public GameObject WoodObstacle_PrefabB;
    [Space(10)]

    [Header("Bridgue Obstacles")]
    public GameObject Bridgue_Prefab;
    [Space(10)]


    [Header("Value Variables")]

    //Objects position var
    public float deltaPos_Obstacles = 1;

    public float spawnWait = 0.5f;
    public Transform surfPlayer;
    public float zOffset;
    [Space(10)]


  
    void Start()
    {
        PoolManager.instance.createPool(FloorLamp_Prefab, 6);
        PoolManager.instance.createPool(Rock_Prefab, 6);
        PoolManager.instance.createPool(Rock_PrefabB, 6);
        PoolManager.instance.createPool(Rock_PrefabC, 6);
        PoolManager.instance.createPool(WoodObstacle_Prefab, 6);
        PoolManager.instance.createPool(WoodObstacle_PrefabB, 6);
        PoolManager.instance.createPool(Bridgue_Prefab, 6);

        for (int i = 0; i < 4; i++)
        {
            generateObstacles();
        }
    }


    void Update()
    {
        surfPlayer = GameObject.Find("PlayableCharacters").GetComponent<PlayableCharacters>().gameCharacter.transform;
        transform.position = new Vector3(transform.position.x, transform.position.y, surfPlayer.position.z + zOffset);
    }


    public void generateObstacles()
    {
        int randomValue = Random.Range(1, 8);

        switch (randomValue)
        {
            case 1:
                spawnObject(FloorLamp_Prefab, CoinFile1_Prefab, 0, - 5.5f ,-90f, 0, 0, true);
                break;

            case 2:
                spawnObject(Rock_Prefab, CoinFile1_Prefab, 0, - 5.5f, -90f, 0, 178, true);
                break;

            case 3:
                spawnObject(Rock_PrefabB, CoinFile3A_Prefab, -8, - 5.5f, 0, 0, 0, false);
                break;

            case 4:
                spawnObject(Rock_PrefabC, CoinFile3A_Prefab, 0, - 5.5f, 0, 0, 0, false);
                break;

            case 5:
                spawnObject(WoodObstacle_Prefab, CoinFile1_Prefab, 0, - 5.5f, -90f, 0, 0, true);
                break;

            case 6:
                spawnObject(WoodObstacle_PrefabB, CoinFile2_Prefab, 0, - 15.5f, 0, 0, 0, false);
                break;

            case 7:
                spawnObject(Bridgue_Prefab, CoinFile1_Prefab, 0, 5f, -90f, 180f, 0, false);
                break;
        }

    }


    public void spawnObject(GameObject prefabObject, GameObject prefabCoin, float CoinXpos ,float yPos, float xRotation , float yRotation, float zRotation, bool randomX)
    {
        if (randomX)
        {
            float Xpos = randomizeX(Random.Range(1, 4));

            PoolManager.instance.ReuseObject(prefabObject, new Vector3(Xpos, yPos, 600 + (100 * deltaPos_Obstacles)), Quaternion.Euler(xRotation, yRotation, zRotation));
            deltaPos_Obstacles++;
        }
        else
        {
            PoolManager.instance.ReuseObject(prefabObject, new Vector3(0, yPos, 600 + (100 * deltaPos_Obstacles)), Quaternion.Euler(xRotation, yRotation, zRotation));
            deltaPos_Obstacles++;
        }
    }


    public float randomizeX(int index)
    {
        float xRandom = 0;
        switch (index)
        {
            case 1:
                xRandom = 0;
                break;

            case 2:
                xRandom = 8;
                break;

            case 3:
                xRandom = -8;
                break;
        }
        return xRandom;
    }


    void OnTriggerExit(Collider other)
    {
        if (other.tag == "Obstacle")
        {
            //other.gameObject.SetActive(false);
            generateObstacles();       
        }
    }


}

There’s somebody know how to spawn new obstacles but without move the objects who are in front of character? Thank you!

I may have misunderstood what you’re asking, but why don’t you just make sure your pool has enough objects, i.e. increase the number of objects?

Hi there,

which ever way you go you will need to implement a way of determining if an obstacle should or shouldn’t be moved.

If it’s an infinite runner perhaps you could use distance as a measure of this. Checking if the obstacle is at least X units away from the player before allowing the script to dispose/reuse the object.

Or only allow objects to be reused if they are outside the cameras view, which is a little more complex than above.

If you maintain two lists, one with objects in use and one with objects that have moved too far from the player and are ready to be used, it will mean you can randomly select from this list in your generateObstacles method.

Kind Regards,
Joe