【Unity】对象池技术
1.简介
对象池(Object Pooling)技术是一种用于优化游戏性能和内存管理的技术。
对象池可以用于各种需要频繁实例化和销毁游戏对象的场景,例如子弹、敌人、玩家等。其主要目标是减少频繁的内存分配和垃圾回收的次数,提高游戏的运行效率,从而提高性能和降低延迟。
在对象池中查找池中隐藏的游戏对象,将其显示出来,以避免一直实例化新的游戏对象,导致游戏性能受到影响。
2.实现
一般地,游戏会需要频繁实例化多种预制体,所以需要先将每种预制体存在各个小池中,接着通过大池进行管理,之后直接从大池中拿取和放回。
小池子(SubPool)代码
using UnityEngine;
using System.Collections.Generic;public class SubPool
{//预制体private GameObject m_prefab;//父对象private Transform m_parent;//小池中所有存在场景的对象private List<GameObject> m_objects = new List<GameObject>();/// <summary>/// 构造函数/// </summary>/// <param name="parent">父对象</param>/// <param name="prefab">预制体</param>public SubPool(Transform parent, GameObject prefab){m_parent = parent;m_prefab = prefab;}/// <summary>/// 预制体名字/// </summary>public string Name{get{return m_prefab.name;}}/// <summary>/// 生成/// </summary>/// <returns>生成的对象</returns>public GameObject Spawn(){GameObject go = null;foreach(GameObject obj in m_objects){if (!obj.activeSelf){go = obj;break;}}if(go == null){go = GameObject.Instantiate(m_prefab);go.transform.parent = m_parent;m_objects.Add(go);}go.SetActive(true);return go;}/// <summary>/// 是否存在小池中/// </summary>/// <param name="go">判断的对象</param>/// <returns></returns>public bool Contains(GameObject go){return m_objects.Contains(go);}/// <summary>/// 回收/// </summary>/// <param name="go">回收的对象</param>public void UnSpawn(GameObject go){if(Contains(go)){go.SetActive(false);}}/// <summary>/// 回收全部/// </summary>public void UnSpawnAll(){foreach(GameObject obj in m_objects){UnSpawn(obj);}}
}
大池子(ObjectPool)代码
using System.Collections.Generic;
using UnityEngine;public class ObjectPool : MonoBehaviour
{//存放预制体的文件名public string FileName = "prefab";//名字-小池子字典private Dictionary<string, SubPool> m_pools = new Dictionary<string, SubPool>();/// <summary>/// 生成/// </summary>/// <param name="name">名字</param>/// <param name="parent">父对象</param>/// <returns>生成的对象</returns>public GameObject Spawn(string name, Transform parent){SubPool pool = null;if(!m_pools.ContainsKey(name)){RegisterNewPool(name, parent);}pool = m_pools[name];return pool.Spawn();}/// <summary>/// 注册新的小池子/// </summary>/// <param name="name">名字</param>/// <param name="parent">父对象</param>private void RegisterNewPool(string name, Transform parent){string path = FileName + "/" + name;GameObject go = Resources.Load<GameObject>(path);if(go != null){SubPool pool = new SubPool(parent, go);m_pools.Add(pool.Name, pool);}else{Debug.Log("未找到" + path + "的预制体");}}/// <summary>/// 回收/// </summary>/// <param name="go">被回收的游戏对象</param>public void UnSpawn(GameObject go){SubPool pool = null;foreach(SubPool p in m_pools.Values){if(p.Contains(go)){pool = p;break;}}if(pool != null){pool.UnSpawn(go);}}/// <summary>/// 回收全部/// </summary>public void UnSpawnAll(){foreach(SubPool p in m_pools.Values){p.UnSpawnAll();}}
}
因为作者精力有限,文章中难免出现一些错漏,敬请广大专家和网友批评、指正。