PoolObject getting always random prefabs

Hey guys!

New guy in unity here, but i was following a tutorial of a endless runner, and my game is for android, and i want to use poolobjects because of performance, but i have two prefabs that i want to randomize, but again initially the script defines a pool of 5 random prefabs and stays that way the entire game, and my goal its to randomize always the prefabs… is there a way to do that?

Thank you!

public class Parallaxer : MonoBehaviour {

class PoolObject {

    public Transform transform;
    public bool inUse;
    public PoolObject(Transform t) { transform = t; }
    public void Use() { inUse = true; }
    public void Dispose() { inUse = false; }
}

[System.Serializable]
public struct YSpawnRange
{
    public float min;
    public float max;
}

public GameObject[] Prefab;
public int poolSize;
public float shiftSpeed;
public float spawnRate;

public YSpawnRange ySpawnRange;
public Vector3 defaultSpawnPos;
public bool spawnImmediate;
public Vector3 immediateSpawnPos;
public Vector2 targetAspectRatio;

float spawnTimer;
float targetAspect;
PoolObject[] poolObjects;
GameManager game;

void Awake()
{
    Configure();
}

void Start()
{
    game = GameManager.Instance;
}

void OnEnable()
{
    GameManager.OnGameOverConfirmed += OnGameOverConfirmed;
}

void OnDisable()
{
    GameManager.OnGameOverConfirmed -= OnGameOverConfirmed;
}

void OnGameOverConfirmed()
{
    for (int i = 0; i < poolObjects.Length; i++)
    {
        poolObjects*.Dispose();*

poolObjects_.transform.position = Vector3.one * 1000;
}
if (spawnImmediate)
{
SpawnImmediate();
}
}
void Update()
{
if (game.GameOver) return;
Shift();
spawnTimer += Time.deltaTime;
if (spawnTimer > spawnRate)
{
Spawn();
spawnTimer = 0;
}
}
void Configure()
{
targetAspect = targetAspectRatio.x / targetAspectRatio.y;
poolObjects = new PoolObject[poolSize];
for (int i = 0; i < poolObjects.Length; i++)
{
var randomIndex = Random.Range(0, Prefab.Length);
GameObject go = Instantiate(Prefab[randomIndex]) as GameObject;
go.SetActive(true);
Transform t = go.transform;
t.SetParent(transform);
t.position = Vector3.one * 1000;
poolObjects = new PoolObject(t);
}
if (spawnImmediate)
{
SpawnImmediate();
}
}
void Spawn()
{
Transform t = GetPoolObject();
if (t == null) return;
Vector3 pos = Vector3.zero;
pos.x = defaultSpawnPos.x;
pos.y = Random.Range(ySpawnRange.min, ySpawnRange.max);
t.position = pos;
}
void SpawnImmediate()
{
Transform t = GetPoolObject();
if (t == null) return;
Vector3 pos = Vector3.zero;
pos.x = immediateSpawnPos.x;
pos.y = Random.Range(ySpawnRange.min, ySpawnRange.max);
t.position = pos;
Spawn();
}
void Shift()
{
for (int i = 0; i < poolObjects.Length; i++)
{
poolObjects.transform.position += -Vector3.right * shiftSpeed * Time.deltaTime;
CheckDisposeObject(poolObjects*);*
}
}
void CheckDisposeObject(PoolObject poolObject)
{
if (poolObject.transform.position.x < -defaultSpawnPos.x)
{
poolObject.Dispose();
poolObject.transform.position = Vector3.one * 1000;
}
}
Transform GetPoolObject()
{
for (int i = 0; i < poolObjects.Length; i++)
{
if (!poolObjects*.inUse)*
{
poolObjects*.Use();*
return poolObjects*.transform;*
}
}
return null;
}
}_

You could make 2 pools one for each object and have it randomize which pool to draw from. Otherwise it can get more complicated to solve if you maintain only one pool of all objects because you always search from the beginning of the pool.

EDIT: To change your paradigm to multiple pools, you can add a Pool class which will internally hold the gameobject instances of each pool like so:

class PoolObject {
	 public Transform transform;
	 public bool inUse;
	 public PoolObject(Transform t) { transform = t; }
	 public void Use() { inUse = true; }
	 public void Dispose() { inUse = false; }
 }
 
class Pool {
	public PoolObject[] poolObjects;
	public GameObject prefab;
	public int poolSize;
}

Then you can essentially set a prefab and poolsize for each pool and fill them up like so:

public Pool[] pools;

void Configure()
{
	targetAspect = targetAspectRatio.x / targetAspectRatio.y;
	int poolCount = pools.Length;
	pools = new Pool[poolCount];
	for (int i = 0; i < poolCount; i++)
	{
		Pool currentPool = pools*;*
  •   	currentPool.poolObjects = new PoolObject[currentPool.poolSize];*
    
  •   	for (int j = 0; j < currentPool.poolSize; j++)*
    
  •   	{*
    
  •   		GameObject go = Instantiate(currentPool.prefab) as GameObject;*
    
  •   		go.SetActive(true);*
    
  •   		Transform t = go.transform;*
    
  •   		t.SetParent(transform);*
    

_ t.position = Vector3.one * 1000;_

  •   		currentPool.poolObjects[j] = new PoolObject(t);*
    
  •   	}*
    
  •   	if (spawnImmediate)*
    
  •   	{*
    
  •   		SpawnImmediate();*
    
  •   	}*
    
  •   }*
    
  • }*
    And also configure your GetPoolObject function to take a pool id parameter:
    Transform GetPoolObject(int poolID)
  • {*
  •   Pool whichPool = pools[poolID];*
    
  •   int poolObjectCount = whichPool.poolObjects.Length;*
    
  •   for (int i = 0; i < poolObjectCount; i++)*
    
  •   {*
    

_ PoolObject poolObject = whichPool.poolObjects*;_
_
if (!poolObject.inUse)_
_
{_
_
poolObject.Use();_
_
return poolObject.transform;_
_
}_
_
}_
_
return null;_
_
}*_
And finally call GetPoolObject with a random int:
var randomIndex = Random.Range(0, pools.Length);
Transform t = GetPoolObject(randomIndex);