- Home /
Random Object Pooler
Hi all, i have an object pooler script which has multiple objects inside it. i have another script which spawns these objects in order, i wish to make this random but i am really stuck. advice greatly appreciated .... public class FinalObjPool : MonoBehaviour { public static FinalObjPool instance;
public List<GameObject> pooledObjects;
public int countToPool = 3;
public bool canExpand = false;
void Awake()
{
if(instance == null)
{
instance = this;
}
pooledObjects = new List<GameObject>();
foreach (GameObject p in platforms)
{
for (int i = 0; i < numOfEachHelix; ++i)
{
GameObject obj = Instantiate(p);
obj.SetActive(false);
pooledObjects.Add(obj);
}
}
}
////// //// i wish to pass a random value in here
public GameObject GetPooledObject()
{
for (int i = 0; i < pooledObjects.Count; i++){
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[i];
}
}
return null;
}
}
//second script//
public class FinalPlatGen : MonoBehaviour {
// Update is called once per frame
void FixedUpdate()
{
OnObjectSpawn();
}
public Transform genPoint;
System.Random rand;
List<int> spawnDegree = new List<int> { 30, 60, 90, 120, 150, 180, 210, 240, 270 };
// Update is called once per frame
public void OnObjectSpawn()
{
if (transform.position.y + 5 < genPoint.position.y)
{
int RotationValue = Random.Range(0, spawnDegree.Count);
int randomVal = spawnDegree[RotationValue];
transform.position = new Vector3(0, transform.position.y + 3, 0);
///i wish to make this part random
GameObject newPlatform = FinalObjPool.instance.GetPooledObject();
if (newPlatform == null)
{
Debug.Log("NONE");
return;
}
newPlatform.transform.position = transform.position;
newPlatform.transform.Rotate(0, randomVal, 0);
newPlatform.transform.SetParent(helix);
newPlatform.SetActive(true);
}
}
}
So you want to randomize the angle, but randomVal is returning the same value every time?
Ah, the website broke the script, so I couldn't tell if that comment was applied to the entire section or that line following it.
Looks like GetPooledObject() goes through the list in order and finds the first object that hasn't been set active yet.
Ins$$anonymous$$d of that, you could use a while() loop, and inside it, you can have i set to a random number between 0 and pooledObjects.length, and you could check if pooledObjects[i] is active or not. If it isn't, that object can be used.
Also, you can reply to comments
Hi @$$anonymous$$asterChameleonGames No basically I have 20 game objects, all different. These objects are added to the pool 3 times each. So all together 60 objects. But when spawning from the pool, they spawn in order. I am looking to spawn them randomly, not in any specific order. Tried many different ways but can't get this to work :(
Answer by Hellium · Apr 30, 2019 at 10:36 PM
public GameObject GetPooledObject()
{
// Filter the list of pooled object and put all the inactive ones into a new list
List<GameObject> inactiveObjects = pooledObjects.FindAll( go => !go.activeInHierarchy );
// Check if the list created above has elements
// If so, pick a random one,
// Return null otherwise
return inactiveObjects.Count > 0 ?
inactiveObjects[ Random.Range(0, inactiveObjects.Count) ] :
null;
}
Nice, but you might want to explain how it works.
I believe a code of 4 lines is not that complicated to understand, only the FindAll
function can be hard to grasp if you have never encountered it. But anyway, I've commented on the code for better clarity.
Well, code of any length can be complicated, and besides, it will be easier for the op to understand and possibly use again.
Answer by Captain_Pineapple · Apr 30, 2019 at 10:41 PM
Hey there,
how about you shuffel your list when you created it? Something along the line:
List<GameObject> shuffeledList = new List<GameObject>();
while(pooledObjects.Count > 0)
{
shuffeledList.Add(pooledObjects[Random.Range(pooledObjects.Count)]);
}
pooledObjects = shuffeledList;
This way you will get the same order of objects but it's not the instantiation order. If this does not work for you, then you have to iterate ovver the whole list, remember the indices that were active and then choose a random value from this list of indices. Another way would be to keep 2 seperate lists, one for active objects, one for inactive. Then you can simply choose any random object from this active list. The latter might even be a bit better on performance.
Let me know what you think or if you need any further information.
good solution, tried both but @Hellium 's solution was more suited. Thanks for your solution too!
Answer by Righteousice · Feb 26, 2021 at 09:35 PM
Was having similar issue: public GameObject GetPooledObject() {
for (int i = 0; i < pooledObjects.Count; i++){
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[i];
}
}
return null;
}
Use:
public GameObject GetPooledObject() {
for (int i = 0; i < pooledObjects.Count; i++){
if (!pooledObjects[i].activeInHierarchy)
{
return pooledObjects[Random.Range(i, pooledObjects.Count];
}
}
return null;
}
This pulled a random pooled object without any issue.
Your answer
