- Home /
Better way to keep track of pooled objects?
So I've finally managed to wrap my head around pooling, and I got it to work now successfully. However, I feel there has to be a cleaner method of keeping track of objects that my enemy spawner can use. (ones that are obviously currently inactive off screen)
Right now, inside function update I'm calling this check every frame.
currentEnemy01 = enemyPrefabs01[currentEnemy01Tracker];
if (currentEnemy01.activeSelf)
{
currentEnemy01Tracker ++;
}
if (currentEnemy01Tracker >= enemyPrefabs01.Length)
{
currentEnemy01Tracker = 0;
}
currentEnemy01Tracker is obviously an int variable I use to keep track of which item I can use next. But the thought of running this check every frame seems a bit on the overkill side.
I've read this answer about a half dozen times now and I still don't fully understand it which is why I ended up just making my own based off of a youtube tutorial I found.
http://answers.unity3d.com/questions/321762/how-to-assign-variable-to-a-prefabs-child.html
What I have right now is working great. I just need a more efficient way of finding the next available object in the pool, which could be any of them because enemies do not typically tend to die in a uniformed order.
Answer by whydoidoit · Mar 11, 2014 at 02:56 PM
You want to use a Stack object onto which you push your instances and Pop them off when you need them.
In javascript you would do this (perhaps in a script call PoolManager):
import System.Collections.Generic;
...
public static pool = new Stack.<Transform>();
public prefab : Transform;
for(var i = 0; i < 10; i++) {
var instance : Transform = Instantiate(prefab);
instance.gameObject.SetActive(false);
pool.Push(instance);
}
Now you can check if you have any:
if(PoolManager.pool.Count > 0) { ...
And get one:
var obj = PoolManager.pool.Pop();
obj.gameObject.SetActive(true);
When you disable you do this:
someObject.gameObject.SetActive(false);
PoolManager.pool.Push(someObject.transform);
You could make it even cleverer by having a Dictionary of stacks like this:
public static pool = new Dictionary.<Transform, Stack.<Transform>>();
Then you could add and retrieve prefabs using the reference to the prefab:
function PoolThis(prefab : Transform) {
if(!pool.ContainsKey(prefab)) {
pool[prefab] = new Stack.<Transform>();
}
for(var i = 0; i < 10; i++) {
var instance : Transform = Instantiate(prefab);
instance.gameObject.SetActive(false);
pool[prefab].Push(instance);
}
}
And check your pools of the different prefabs like this:
if(PoolManager.pool[somePrefab].Count > 0) {...
Stack is a .NET thing so mostly doc'd in Cs but works fine in js
Don't use the Unity JS Array class; it's slow and untyped.
It have something on the enemy that references it's prefab then you just do:
Pool$$anonymous$$anager.pool[thisEnemy.prefab].Push(thisEnemy.transform);
I mean create a script that has a variable which you set to be the prefab you used to create it.
public Transform prefab;
Your answer
Follow this Question
Related Questions
Setting Scroll View Width GUILayout 1 Answer
Grabbing an object from array 0 Answers
Using an object pool with Javascript. 1 Answer
Objects in object pool not reactivating. 1 Answer
Object Pooling With JavaScrip 0 Answers