Skip to content
  • Home
  • UNITY TUTORIALS
  • OUR GAMES

Aliasing Games DevBlog

Journey about making games.

Object pooling in Unity

By: jtyma
On: June 2, 2016
In: FastTrick
Tagged: C#, Unity
With: 0 Comments

Object pooling in Unity

c#_icon512If you don’t know what is object pooling, it’s a perfect time to learn this technique. It’s not complicated so it’s easy to understand even for beginners. You can create complex games in Unity without object pooling but this approach can save a few frames which affects overall users’ comfort.

Introduction

Let’s assume that we are creating shooter game. There is a main character which holds machine guns. If player clicks fire button, character fires tons of bullets per second. We also want to remove these bullets from the scene after a moment of time. It requires calling Instantiate and Destroy functions many times. It’s not a secret that new object’s creation is resource consuming. If many objects are creating and removing from the scene, Garbage Collector can be started to remove unnecessary objects from memory. This may result in game’s slowdown which is very undesirable.

Better approach is to reuse once created objects. If our game needs more bullets, we create them. If we don’t need them anymore, we disable them instead of removing it from the scene.

Object pooling – example

Today, our goal is to create a simple example with object pooling. We will create sample scene with two spawners. The first spawner will create objects in ‘traditional’ way and the second one will use object pooling. To make it as simple as possible, spawners will create cubes and spheres which fall from the top of the screen.

First, create generic spawner’s script:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
using UnityEngine;
using System.Collections;
 
public class Spawner : MonoBehaviour {
 
public GameObject spawnables; // objects holder
 
public float interval = 0.1f; // delay between spawns
 
public int spawnedObjects; // we want to check how many objects we spawned so far
 
void Awake () {
spawnedObjects = 0;
}
 
void Start () {
StartCoroutine (SpawnCoroutine ()); // start spawning coroutine
}
 
// this function is set as virtual, we will override it in our spawners
public virtual GameObject GetObject () {
return null;
}
 
// here we set all necessary object's properties like start position and parent transform
public void InitObject (GameObject go) {
if (go != null) {
Vector3 randomPosition = transform.position;
randomPosition.x = Random.Range (-(transform.localScale.x / 2f), (transform.localScale.x / 2f));
randomPosition.x += transform.position.x;
go.transform.position = randomPosition;
go.transform.parent = spawnables.transform;
go.GetComponent<Rigidbody> ().velocity = Vector3.zero;
go.SetActive (true);
}
}
 
private IEnumerator SpawnCoroutine () {
while (true) {
InitObject (GetObject ()); // get object to spawn and set its properties
yield return new WaitForSeconds (interval);
}
}
}

which implements all necessary functionalities. It contains SpawnCoroutine (read more about coroutines: Coroutines – the first encounter!) which is responsible for periodically objects creation. There is also InitObject method which sets object’s random position (based on spawner’s scale and position), resets its speed and set it as active. Virtual function GetObject will be overridden in target spawners’ implementions.

To create ‘classic’ spawner we used this script:

C#
1
2
3
4
5
6
7
8
9
10
11
12
using UnityEngine;
using System.Collections;
 
public class ClassicSpawner : Spawner {
 
public GameObject prefab; // object to be spawned
 
public override GameObject GetObject () {
spawnedObjects++;
return Instantiate (prefab) as GameObject; // just return new object
}
}

As you can see, we used inheritance. As a prefab we will use a cube with rigidbody attached. Spawner with object pooling is created with:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
using UnityEngine;
using System.Collections;
 
public class SpawnerWithPooler : Spawner {
 
private Pooler pooler;
 
void Awake () {
pooler = GetComponent<Pooler> (); // get object pool component
}
 
public override GameObject GetObject () {
GameObject go = pooler.GetObject (); // tell pooler that we need another object to spawn
spawnedObjects = pooler.PooledObjectsCount (); // get pool's size
return go;
}
}

There is the most interesting part. This spawner uses Pooler object (as component attached to second spawner) to get new objects instances. Pooler‘s script is shown below:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
 
public class Pooler : MonoBehaviour {
 
public GameObject prefab; // object to be spawned
 
private List<GameObject> objects = new List<GameObject> (); // list of currently spawned objects
 
public GameObject GetObject () {
GameObject result = null;
// first, check if there is an unused object in the pool
for (int i = 0; i < objects.Count; i++) {
if (!objects [i].activeInHierarchy) { // if there is an unused one
result = objects [i]; // get its reference
break;
}
}
// if result is still null which means that we don't have available objects
if (result == null) {
result = Instantiate (prefab) as GameObject; // create new
result.SetActive (false); // set it as inactive
objects.Add (result); // add to pool
}
 
return result;
}
 
public int PooledObjectsCount () {
return objects.Count;
}
}

Pooler contains only two funtions. GetObject function checks if there is an unused object in the pool. If not, it creates new object and adds it to list (read more about Collections in C# and Unity). This script is completely generic so it can be used for pooling every kind of objects you need. You can combine it with singleton pattern to make it accessible from everywhere.

Ok. We said that our scene should contain two spawners so we need two collectors also. First one will destroy objects and the second one will just disable them. We created simple Collector script:

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
using UnityEngine;
using System.Collections;
 
public class Collector : MonoBehaviour {
 
public bool destroyOnTouch = true;
 
void OnTriggerEnter (Collider c) {
if (destroyOnTouch)
GameObject.Destroy (c.gameObject);
else
c.gameObject.SetActive (false);
}
}

Next, create objects like in the screen:

object pooling

Red Spawner and Collector is our ‘classic’ implementations and the green ones are created with object pooling. Take a look at this animation to see how it works:

object pooling

One important thing! Spawned objects don’t interact with themselves. We used Physics Layers (read more here: Physics layers in Unity) to be sure that cubes and spheres don’t interfere with each other. It look’s like the spawners work in the same manner but check Inspector to see the difference. There are only about 25 spawned objects with object pooling. ‘Classic’ spawner will create as many objects as possible. It will make Garbage Collector busy in a short period of time.

We hope that everything is clear. As usual we share with you complete project here: Download

Do you have any questions? Comment below 🙂

+11
Tweet
Share2
Share
Shares 3

Related

2016-06-02
Previous Post: Game of Life – Unity implementation
Next Post: Extension methods in C# and Unity

Click to play New Tap Order 2!

New Tap Order 2

Navigate

  • Home
  • UNITY TUTORIALS
  • OUR GAMES

Follow us on Twitter

My Tweets

Designed using Dispatch WordPress Theme. Powered by WordPress.