unity 对象池
using System.Collections; using System.Collections.Generic; using UnityEngine; //对象类 public class Poolable:MonoBehaviour { public string key = string.Empty;//键 public bool isPooled = false;//判断创建的预制体对象是否存在对象池 public GameObject gameObject;//游戏对象 }
对象池管理类
using System.Collections; using System.Collections.Generic; using UnityEngine; public class GameObjectPoolController : MonoBehaviour { private static GameObjectPoolController m_instance;//单例 private static Dictionary<string, PoolData> pools = new Dictionary<string, PoolData>();//保存key到PoolData类的映射关系 public static GameObjectPoolController m_Instance { get { if(m_instance==null) { CreateSharedInstance(); } return m_instance; } } void Awake() { if(m_instance!=null&&m_instance!=this) { Destroy(m_instance); } else { m_instance = this; } } // Start is called before the first frame update void Start() { } // Update is called once per frame void Update() { } /// <summary> /// 设置内存中对象可存储最大数目 /// </summary> /// <param name="key"></param> /// <param name="maxCount"></param> public static void SetMaxCount(string key,int maxCount) { if (!pools.ContainsKey(key))//对象池没有该对象 { return; } PoolData data = pools[key]; data.maxCount = maxCount; } /// <summary> /// 指定key映射到预制体 /// 预创建多少对象 /// </summary> /// <param name="key"></param> /// <param name="prefab"></param> /// <param name="prepopulateNum"></param> /// <param name="maxCount"></param> /// <returns></returns> public static bool AddEntry(string key,GameObject prefab,int prepopulateNum,int maxCount) { if (pools.ContainsKey(key))//对象池已存在该对象 { return false; } PoolData data = new PoolData(); data.prefab = prefab; data.maxCount = maxCount; data.pool = new Queue<Poolable>(); pools.Add(key, data);//加入到对象池 for(int i = 0; i < prepopulateNum; i++) { Enqueue(CreateInstance(key, prefab));//入队 } return true; } /// <summary> /// 根据键值清除对象池中的对象 /// </summary> /// <param name="key"></param> public static void ClearEntry(string key) { if (!pools.ContainsKey(key))//无对象 { return; } PoolData data = pools[key]; while (data.pool.Count > 0) { Poolable poolable = data.pool.Dequeue(); if (poolable != null) { Destroy(poolable.gameObject); } } pools.Remove(key); } /// <summary> /// 将创建对象存储到对象池中 /// </summary> /// <param name="sender"></param> public static void Enqueue(Poolable sender) { if(sender==null||sender.isPooled||!pools.ContainsKey(sender.key)) { return; } PoolData data = pools[sender.key]; if (data.pool.Count >= data.maxCount) { GameObject.Destroy(sender.gameObject); return; } data.pool.Enqueue(sender); sender.isPooled = true; sender.gameObject.transform.SetParent(m_Instance.transform);//把父节点设为对象池 sender.gameObject.SetActive(false);//不可见 } /// <summary> /// 从对象池中取对象 /// </summary> /// <param name="key"></param> /// <returns></returns> public static Poolable Dequeue(string key) { if(!pools.ContainsKey(key))//不存在 { return null; } PoolData data = pools[key]; if (data.pool.Count == 0) { return CreateInstance(key, data.prefab); } Poolable poolable = data.pool.Dequeue(); poolable.isPooled = false; return poolable; } /// <summary> /// 创建游戏对象实例,为游戏对象实例添加Poolable脚本 /// 设置游戏对象属性 /// </summary> /// <param name="key"></param> /// <param name="prefab"></param> /// <returns></returns> public static Poolable CreateInstance(string key,GameObject prefab) { GameObject gameObject = Instantiate(prefab) as GameObject; Poolable poolable = gameObject.AddComponent<Poolable>(); poolable.key = key; poolable.gameObject = gameObject; return poolable; } /// <summary> /// /// </summary> public static void CreateSharedInstance() { GameObject gameObject = new GameObject("GameObjectPoolController"); m_instance = gameObject.AddComponent<GameObjectPoolController>(); DontDestroyOnLoad(gameObject);//页面切换不被销毁 } }
对象池中的对象管理类
using System.Collections; using System.Collections.Generic; using UnityEngine; public class PoolData : MonoBehaviour { public GameObject prefab = null;//新建对象实例的预制体 public int maxCount = 0;//内存中可以存储的对象最大数目 public Queue<Poolable> pool;//存储可重用对象实例 }