-
Notifications
You must be signed in to change notification settings - Fork 2k
Object Pooling
Object pooling aims to alleviate the performance hit of instantiating/destroying many objects by instantiating them beforehand, and then activating/deactivating the objects instead, reusing objects when needed.
This is a common pattern in videogames even outside of Unity, but we have enriched it by using some Unity-specific features like ScriptableObjects as templates to setup pools directly in the Editor, without code.
- Creating a new poolable type
- Creating a factory for the new poolable type
- Creating a pool for the new poolable type
- Using the pool
- More info
using UOP1.Pool;
using UnityEngine;
public class MyPoolableComponent : MonoBehaviour, IPoolable
{
public void OnRequest()
{
}
public void OnReturn(Action onReturned)
{
onReturned.Invoke();
}
}
using UnityEngine;
using UOP1.Factory;
[CreateAssetMenu(fileName = "MyPoolableComponentFactory", menuName = "Factory/MyPoolableComponent")]
public class MyPoolableComponentFactorySO : FactorySO<MyPoolableComponent>
{
public override MyPoolableComponent Create(){
return new GameObject("MyPoolableComponent").AddComponent<MyPoolableComponent>();
}
}
using UnityEngine;
using UOP1.Pool;
using UOP1.Factory;
[CreateAssetMenu(fileName = "MyPoolableComponentPool", menuName = "Pool/MyPoolableComponent")]
public class MyPoolableComponentPoolSO : ComponentPoolSO<MyPoolableComponent>
{
[SerializeField]
private MyPoolableComponentFactorySO _factory;
[SerializeField]
private int _initialPoolSize;
public override IFactory<MyPoolableComponent> Factory
{
get
{
return _factory;
}
set
{
_factory = value as MyPoolableComponentFactorySO;
}
}
public override int InitialPoolSize
{
get
{
return _initialPoolSize;
}
set
{
_initialPoolSize = value;
}
}
}
There are two ways to use a pool. Either you can create the pool and factory as an asset in the project and set it to an object reference in the inspector or you can create the pool and factory at runtime.
As an asset:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyPoolManager : MonoBehaviour
{
[SerializeField]
private MyPoolableComponentPoolSO _pool = default;
private void Start()
{
MyPoolableComponent myPoolableComponent = _pool.Request();
//Do something with it
_pool.Return(myPoolableComponent);
}
}
At runtime:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MyRuntimePoolManager : MonoBehaviour
{
[SerializeField]
private int _initialPoolSize = 5;
private MyPoolableComponentPoolSO _pool;
private void Start()
{
_pool = ScriptableObject.CreateInstance<MyPoolableComponentPoolSO>();
_pool.name = gameObject.name;
_pool.Factory = ScriptableObject.CreateInstance<MyPoolableComponentFactorySO>();;
_pool.InitialPoolSize = _initialPoolSize;
MyPoolableComponent myPoolableComponent = _pool.Request();
//Do something with it
_pool.Return(myPoolableComponent);
}
}
To learn more about object pooling in general, check out the following links:
Unity Open Projects - Open-source games made by Unity + the community
We are looking forward to see what you will create ❤
- the Unity Creator Advocacy team
- Game architecture overview
- Playing the game in Unity
- Creating a new playable scene
- Building the game
The game systems explained, with API examples. For programmers.
- Event system
- State machine
- Input
- Object pooling
- Runtime anchors
- Audio system
- Narrative
- Dialogue system
- Cutscenes system
- Inventory and Cooking
- Combat
- User Interface
How-tos for designers to expand the game's gameplay.
- Adding quests
- Adding items
- Creating dialogues
- Making a cutscene