Unity2d development - Object Pool

motivation

We know that generating and destroying gameobject objects of a game in unity consumes certain resources. Frequent generation and destruction of object memory will have great pressure, such as particle effects of particle system, bullets fired by guns, frequently generated gold coins, etc. Frequent generation and destruction of these objects can easily cause memory fragmentation, so we need a way to solve this problem, which is object pool.

principle

Define an object pool, which contains a group of reusable objects. Each object supports querying the "state" of the object to determine whether the object is in use. When the object pool is initialized, a dictionary is automatically created to store objects.

1, When you need to use objects:

1) If the object exists in the object pool and the "state" of the object is not in use, the object is obtained directly from the collection.

2) If there is no object in the object pool, but the "state" of the object is in use, create a new object and add it to the collection, and then return the new object.

2, When you need to destroy an object:

1) Directly set the object's state to unused.

Use timing

Object pool is widely used for visible things, such as game entities and visual effects, but it can also be used on less visual data structures, such as playing sound. Use object pools when:

  • Objects need to be created and destroyed frequently
  • Similar object size
  • Object memory allocation on the heap is slow or can cause memory fragmentation.
  • Each object encapsulates expensive and reusable resources such as databases or network connections. (I don't know what I saw in other articles)

Object pool patterns · Optimization Patterns · game design patterns  --- Here is the original text. I recommend you to take a look at this game design mode. It's very good.

Example code of my project:

I briefly annotated it.

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class ObjectPool
{
    private static ObjectPool instance;
    private Dictionary<string,Queue<GameObject>> objectPool= new Dictionary<string,Queue<GameObject>>();
    //The parent object pool stores objects in the object pool to prevent window clutter
    private GameObject pool;
    public static ObjectPool Instance
    {
        get{
            if(instance == null)
            {
                instance = new ObjectPool();
            }
            return instance;
        }
    }
    public GameObject GetObject(GameObject prefab)
    {
        GameObject _object;
        //Check whether the object pool contains the preform with this name, and then check the number of objects to be allocated in the pool
        if(!objectPool.ContainsKey(prefab.name) || objectPool[prefab.name].Count == 0)
        {
            _object = GameObject.Instantiate(prefab);   
            //If there is no object with this name in the object pool (Dictionary key value pair) or there is no object to be allocated in the object pool, instantiate a new object and put it into the pool using the push function
            PushObject(_object);
            //Then judge whether there is an object pool in the scene, and create one if the parent object pool does not exist
            if(pool == null)
            {                   
                pool = new GameObject("ObjectPool");
            }
            GameObject child = GameObject.Find(prefab.name);
            //Find out whether the parent object of the child object pool exists in the scene. If it does not exist, create a new object with the name of the preform and set it as the child object of the object pool object
            if (!child)
            {
                child = new GameObject(prefab.name);
                child.transform.SetParent(pool.transform);  
            }
            _object.transform.SetParent(child.transform);
        }
        _object = objectPool[prefab.name].Dequeue();
        _object.SetActive(true);
        return _object;
    }
    //Get the preform and add the preform to the dictionary queue
    public void PushObject(GameObject prefab)
    {
        string _name = prefab.name.Replace("(Clone)", string.Empty);
        //If there is no key named name, add the name queue to the object pool
        if (!objectPool.ContainsKey(_name))
        {
            objectPool.Add(_name, new Queue<GameObject>());
        }
        //List
        objectPool[_name].Enqueue(prefab);
        prefab.SetActive(false);
    }
}

Tags: C# Unity

Posted on Thu, 21 Oct 2021 00:29:34 -0400 by tommy445