“This article has participated in the good article call order activity, click to see: back end, big front end double track submission, 20,000 yuan prize pool for you to challenge!”

Object pooling

1. Simple object pool definition

Object pooling is a memory management service used by Unity to reduce the overhead of creating each object for objects that need to disappear frequently. Instead of destroying the object, we SetActive(false) and Queue it. When we want to display a new object, we go to the pool to see if there are hidden objects, and we fetch SetActive(true). If the pool is not available then re-instantiate.

2. Reason for using the object pool

In Unity game development, new objects are often created. If the number of new objects is small, it is acceptable. If the number of new objects is large, then it is a great problem for memory. Shooting game, for example, each launch a bullet, is to create a new object of bullets, then the bullet is huge, it is conceivable that a game created many new objects, so if these bullets to create all of the game to play the role of a key and sustainability are understood, the problem is the bullet fired is completed, After a few seconds it no longer has any meaning and is automatically hidden, which we call SetActive (false), so a large number of inactive objects appear in the game scene.

Since the objects in the object pool are only SetActive (false), they are not actually destroyed, so they are usually used for objects that are often used in games or that require a lot of generation. You can’t use this technique on all objects, and it’s not worth the effort to do otherwise.

3. Create and use a simple object pool

There is a Queue to hold the objects in the pool, and then we implement two methods, one to fetch and one to put the objects. When fetching objects, if there is an object available in the pool then take out one, if not Instantiate one; To put an object is to SetActive(false) the object and put it in the pool. Here is a simple effect

First there is a singleton.cs for writing other scripts as singletons

namespace Utilty
{
    public class Singleton<T>
    {
        private static T instance;
        public static T GetInstance()
        {
            if (instance == null)
            {
                instance = (T)Activator.CreateInstance(typeof(T), true);
            }
            returninstance; }}}Copy the code

Assetsmanager.cs is used to load the generated game object

using System.Collections.Generic;
using UnityEngine;

// General framework
namespace Utilty
{
    public class AssetsManager : Singleton<AssetsManager>
    {
        protected AssetsManager()
        {
            assetsCache = new Dictionary<string, Object>();
        }
        // Cache dictionary
        private Dictionary<string, Object> assetsCache;

        // Get resources
        public virtual T GetAssets<T> (string path) where T : Object
        {
            // Check whether this resource is in the cache pool
            if (assetsCache.ContainsKey(path))
            {
                // Return the resource directly
                return assetsCache[path] as T;
            }
            else
            {
                // Load resources with Resource.Load
                T assets = Resources.Load<T>(path);
                // Load the new resource into the cache pool
                assetsCache.Add(path,assets);
                // Return the resource
                returnassets; }}// Uninstall unused resources
        public void UnloadUnusedAssets()
        {
            / / unloadingResources.UnloadUnusedAssets(); }}// Load the image
    public class SpriteManager : Singleton<SpriteManager> {}public class PrefabManager : Singleton<PrefabManager>
    {
        private PrefabManager(){}public GameObject CreateGameObjectByPrefab(string path)
        {
            // Get the default body
            GameObject prefab = AssetsManager.GetInstance().GetAssets<GameObject>(path);
            / / generated
            GameObject obj = Object.Instantiate(prefab);
            / / return
           return obj;
        }
        public GameObject CreateGameObjectByPrefab(string path, Vector3 pos, Quaternion qua)
        {
            // Generate the object
            GameObject obj = CreateGameObjectByPrefab(path);
            // Set the coordinates and rotation
            obj.transform.position = pos;
            obj.transform.rotation = qua;
            / / return
            return obj;
        }

        public GameObject CreateGameObjectByPrefab(string path, Transform parent, Vector3 localPos, Quaternion localQua)
        {
            // Generate the object
            GameObject obj = CreateGameObjectByPrefab(path);
            // Set the parent object
            obj.transform.SetParent(parent);
            // Set the coordinates and rotation
            obj.transform.localPosition = localPos;
            obj.transform.localRotation = localQua;
            / / return
            returnobj; }}}Copy the code

Objectpool. cs is used to generate and reclaim game objects from the ObjectPool

using System.Collections.Generic;
using UnityEngine;

namespace Utilty
{
   public class ObjectPool : Singleton<ObjectPool>
{
    // Private constructs
    private ObjectPool()
    {
        pool = new Dictionary<string, List<GameObject>>();
    }

    / / object pool
    private Dictionary<string, List<GameObject>> pool;
    // Generate game objects from the object pool
    public GameObject SpawnObject(string name)
    {
        GameObject needObj;
        // Check whether there is a subpool corresponding to the name and there are objects in the subpool
        if (pool.ContainsKey(name) && pool[name].Count > 0)
        {
            // Return object 0
            needObj = pool[name][0];
            // Remove object 0 from List
            pool[name].RemoveAt(0);
        }
        else
        {
            Instantiate Instantiate Instantiate Instantiate Instantiate
            needObj = PrefabManager.GetInstance().CreateGameObjectByPrefab(name);
            // Change the name (delete Clone)
            needObj.name = name;
        }
        // Set to active
        needObj.SetActive(true);
        / / return
        return needObj;
    }

        /// <summary>
        ///Reclaim game objects to the object pool
        /// </summary>
        /// <param name="Objname"></param>
        public void RecycleObj(GameObject Objname)
    {
            // To prevent it from being seen, set it to inactive
            Objname.SetActive(false);
            if (pool.ContainsKey(Objname.name))
            {
                // Put the current object into the object subpool
                pool[Objname.name].Add(Objname);
            }
            else
            {
                // Create the subpool and place the objects in
                pool.Add(Objname.name, newList<GameObject> { Objname }); }}}}Copy the code

The poolObject. cs is used to delay reclaiming objects

using System.Collections;
using UnityEngine;
using Utilty;

public class PoolObject : MonoBehaviour
{
    private void OnEnable()
    {
        StartCoroutine(DelayRececle(2));
    }
    // Delay recovery coroutines
    IEnumerator DelayRececle(float interval)
    {
        // Wait a few seconds
        yield return new WaitForSeconds(interval);
        // Reclaim the current objectObjectPool.GetInstance().RecycleObj(gameObject); }}Copy the code

Demo.cs is used for simple object pooling techniques

using UnityEngine;
using Utilty;

public class Demo : MonoBehaviour
{
    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.J))
        {
            GameObject go = ObjectPool.GetInstance().SpawnObject("Prefab"); go.transform.position = Vector3.zero; go.transform.rotation = Quaternion.identity; go.GetComponent<Rigidbody>().velocity = Vector3.zero; }}}Copy the code