“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