Reusing GameObjects in Unity3D

Reuse GameObjects instead of creating new ones for better performance

Kristoffer Karlsson
3 min readMar 19, 2017

--

Instantiating and destroying game objects in unity is a very expensive process and a common thing beginners don’t think about. When you work with a lot of game objects it’s crucial to reuse them for good performance.

The Handler class

The Handler is responsible for retrieving, activating, deactivating and instantiating new game objects. The handler will instantiate X amount prefabs when being constructed and can automatically instantiate more objects if needed. Using the Handler class may increase the loading time of your game since objects are being instantiated upon construction of the handler but it will speed up the overall performance later. You should have one Handler for each prefab.

public class Handler  
{
private bool _isDoneLoading;
private GameObject _prefab;
private GameObject[] _pool;
private List<GameObject> _loosePool;
private int _poolSize;
private int _maxLooseSize;
private bool _expandable; public GameObject[] Pool { get { return _pool; } }
public List<GameObject> LoosePool { get { return _loosePool; } }
public Handler(GameObject prefab,int poolSize, bool expandable = true, string parent = "")
{
_prefab = prefab;
_poolSize = poolSize;
_maxLooseSize = _poolSize/4;
var defaultPos = new Vector3(); Transform parentTrans = null;
if (!String.IsNullOrEmpty(parent))
{
parentTrans = GameObject.Find(parent).transform;
}
_pool = new GameObject[_poolSize];
_loosePool = new List<GameObject>();
for (int i = 0; i < _poolSize; i++)
{
var gm = (GameObject)GameObject.Instantiate(_prefab, defaultPos, Quaternion.identity);
gm.SetActive(false);
_pool[i] = gm;
if (parentTrans != null)
{
gm.transform.parent = parentTrans;
}
}
_expandable = expandable; _isDoneLoading = true;
}
public GameObject RetrieveInstance(Vector3 position, Quaternion rotation)
{
for (int i = 0; i < _poolSize; i++)
{
var gm = _pool[i];
if (gm != null && !gm.activeSelf)
{
gm.transform.position = position;
gm.transform.rotation = rotation;
gm.SetActive(true);
return gm;
}
}
if (_expandable)
{
var newGm = (GameObject) GameObject.Instantiate(_prefab, position, rotation);
_loosePool.Add(newGm);
if (_loosePool.Count >= _maxLooseSize)
{
var temp = _pool.ToList();
temp.AddRange(_loosePool);
_pool = temp.ToArray();
_loosePool.Clear();
}
return newGm;
}
return null;
}
public void DeactivateAll()
{
for (int i = 0; i < _poolSize; i++)
{
_pool[i].SetActive(false);
}
}
public bool IsDoneLoading()
{
return _isDoneLoading;
}
}

The Handler class takes four parameters.

GameObject prefab

The prefab the Handler should instantiate.

int poolSize

Amount of instantiated game objects. If the pool size is too large, then we will use unnecessary amount of memory. If it’s too low, then the handler will start instantiating more Game Objects (if expandable is true) during run time and that will decrease the performance.

bool expandable

If the handler should be able to instantiate more game objects or not (default is true).

string parent

The parent Game Object instantiated objects will be placed under in the tree. Default is null “root”.

Usage

  • Construct the Handler in the beginning of your scene.
  • Call RetrieveInstance whenever you need a new game object.
  • When you are done then simply call SetActive(false) on the game object.

BTC

1CGu9Ctt1AuyXiWMJ2nEDoH1RRAKtStdjx

ETH

0xd2291b554075da7f61210db2648a7f0a2d006190

--

--

Kristoffer Karlsson

Software developer and indie game developer from Sweden. Been turning coffee into code since 2010.