using System.Collections; using System.Collections.Generic; using UnityEngine; /******************************************************************************* *Create By CG *Function 对象池管理_小池子 *******************************************************************************/ namespace ZXK.Framework { public class ObjectPool : MonoBehaviour { //这个对象池存储的游戏对象的预制体 public GameObject _Prefab; //对象池最多能容纳多少个游戏对象。负数表示可以容纳无数个。 private const int _capacity = 15; //从这个对象池中取出并正在使用的游戏对象。 public List _UsedGameObjectList = new List(); //存在这个对象池中没有被使用的游戏对象。 public List _UnusedGameObjectList = new List(); //这个对象池中正在使用和没有被使用的游戏对象的总数。 public int _TotalGameObjectCount { get => _UsedGameObjectList.Count + _UnusedGameObjectList.Count; } /// /// 从对象池获取一个对象,并返回这个对象。 /// 如果对象池有,从对象池中取出来用。 /// 如果对象池没有,则实例化该对象。 /// /// /// /// /// public GameObject Spawn(Vector3 position, Quaternion rotation, Transform parent = null) { //要实例化的游戏对象 GameObject go; //如果对象池中有,则从对象池中取出来用。 if (_UnusedGameObjectList.Count > 0) { go = _UnusedGameObjectList[0]; _UnusedGameObjectList.RemoveAt(0); _UsedGameObjectList.Add(go); go.transform.localPosition = position; go.transform.localRotation = rotation; go.transform.SetParent(parent, false); go.SetActive(true); } //如果对象池中没有,则实例化该对象。 else { go = Instantiate(_Prefab, position, rotation, parent); _UsedGameObjectList.Add(go); } //如果该游戏对象身上继承MonoBehaviour的脚本中写了名叫OnSpwan的方法,则会执行它们一次。 go.SendMessage("OnSpawn", SendMessageOptions.DontRequireReceiver); return go; } /// /// 隐藏指定的游戏对象,并把它回收进对象池中。 /// /// public void Despawn(GameObject go) { if (go == null) return; //遍历这个对象池中所有正在使用的游戏对象 for (int i = 0; i < _UsedGameObjectList.Count; i++) { if (_UsedGameObjectList[i] == go) { //如果这个对象池的容量不为负数,且容纳的游戏对象已经满,则把0号的游戏对象删除掉,确保之后新的游戏对象能放入池子中。 if (_capacity >= 0 && _UnusedGameObjectList.Count >= _capacity) { Destroy(_UnusedGameObjectList[0]); _UnusedGameObjectList.RemoveAt(0); } //把游戏对象回收到对象池中 _UnusedGameObjectList.Add(go); _UsedGameObjectList.RemoveAt(i); //如果该游戏对象身上继承MonoBehaviour的脚本写了名叫OnDespawn的方法,则在回收的时候,会执行一次。 go.SendMessage("OnDespawn", SendMessageOptions.DontRequireReceiver); go.SetActive(false); go.transform.SetParent(transform, false); return; } } } /// /// 把通过这个对象池生成的所有游戏对象全部隐藏并放入对象池中 /// public void DespawnAll() { int count = _UsedGameObjectList.Count; for (int i = 1; i <= count; i++) { Despawn(_UsedGameObjectList[0]); } _UsedGameObjectList.Clear(); } /// /// 预先往这个对象池中加载指定数量的游戏对象 /// public void Preload(int amount = 1) { if (_Prefab == null) return; if (amount <= 0) return; for (int i = 1; i <= amount; i++) { GameObject go = Instantiate(_Prefab, Vector3.zero, Quaternion.identity); go.SetActive(false); go.transform.SetParent(transform, false); _UnusedGameObjectList.Add(go); go.name = _Prefab.name; } } } }