Is there any sample code for GameObject pooling? I’ve written a script to do pooling, but when I try to fill out the transforms for a used object, it still seems to have some of the old data in it.
“Pooling”? In what sense?
He probably means reusing already instantiated objects, so you don’t have to recreate them all the time and suffer the garbage collection cost.
Yes, I want to avoid the instantiation (both to avoid construction, memory allocation, and chance of GC).
Does Unity already do that for you behind the scenes? What is Unity’s overhead on instantiation? High?
No it’s not high. I’ve done things like asteroid belts and starfields.
On the iPhone, I’m seeing bad GC pauses. So I need to Instantiate at the beginning of time and not cycle my objects. So, I need to pool them.
Somebody else has got to have dealt with this right?
Moderator, this is more of an iPhone issue. Can this be moved to the iPhone list?
An easy way that comes to mind is to allocate an array, and push them onto a Queue or Stack. Then, once you need them, pop them off the Queue/Stack, and once you want done with the GO, make any state resets and push them back on.
After some careful profiling, it appears that memory/GC is not the issue, but rather something about first instantiation that’s killing me.
In case you still wanted it, here’s a quick pool class that I wrote. I use the word ball in the name, but its really for any type of object. You may also need to do some additional physics changes when you deactivate. Velocity is the only thing I needed to zero out.
using UnityEngine;
using System;
using System.Collections;
public class BallManager : MonoBehaviour
{
public int TableSize = 0;
public GameObject Prefab = null;
public int TableSizeIncrease = 5;
private Stack freeObjects = null;
private bool managerEnabled = false;
public void Awake()
{
if (this.Prefab == null || this.TableSize == 0)
{
Debug.LogError("BallManager: No prefab or table size is 0");
return;
}
freeObjects = new Stack();
// build the stack
CreatePrefabs(this.TableSize);
}
public GameObject NewBall()
{
if (freeObjects.Count == 0)
{
CreatePrefabs(this.TableSizeIncrease);
}
return freeObjects.Pop() as GameObject;
}
public void DeactivateBall(GameObject ball)
{
ball.active = false;
ball.rigidbody.velocity = Vector3.zero;
freeObjects.Push(ball);
}
private void CreatePrefabs(int count)
{
for(int i = 0; i < count; i++)
{
GameObject prefabClone = Instantiate(this.Prefab, Vector3.zero, Quaternion.identity) as GameObject;
prefabClone.active = false;
prefabClone.name = "prefab " + prefabClone.GetInstanceID();
freeObjects.Push(prefabClone);
}
}
}