|
需求
外部传入GameObject模板,从对象池中获取该模板的实例进行使用;
使用完毕后,传入模板和之前获取的实例,将该实例还给对象池。
思路
对象池持有一个字典:模板-对象池元素集合
对象池元素集合是自己写的一个类:其中维护了模板对应的具体实例。
用法
外部在游戏开始时主动Init对象池,游戏结束时主动Destroy对象池。
从对象池中获取实例后,需自行SetActive(true)该实例。
返还实例时,需传入正确的实例对应的模板(对象池本身无法检查传入的是否是正确的。也可通过其他方式检测,如为每个实例添加用于标记的Component)。
具体代码
using System.Collections;using System.Collections.Generic;using UnityEngine;/// <summary>/// 外界可以传入GO模板,获取GO实例/// </summary>public class GOPool : MonoBehaviour{ public static GOPool Instance{ get; private set; } private Dictionary<GameObject, GOPoolObj> _goPoolDict; public static void Init() { if (Instance == null) { GameObject go = new GameObject(nameof(GOPool)); Instance = go.AddComponent<GOPool>(); Instance._goPoolDict = new Dictionary<GameObject, GOPoolObj>(); } else { Debug.Log("已有Instance,不可再次Init。若确需Init,请先调用Destroy!"); } } public void Destroy() { foreach (var value in _goPoolDict.Values) { value.Destroy(); } _goPoolDict.Clear(); _goPoolDict = null; Instance = null; } public GameObject GetInstance(GameObject goTemplate) { EnsureDictHasKey(goTemplate); return _goPoolDict[goTemplate].GetInstance(); } public void RecycleInstance(GameObject goTemplate, GameObject go) { EnsureDictHasKey(goTemplate); _goPoolDict[goTemplate].RecycleInstance(go); } private void EnsureDictHasKey(GameObject key) { if (!_goPoolDict.ContainsKey(key)) { var go = new GameObject(key.name); go.transform.SetParent(transform); var goPoolObj = new GOPoolObj(go, key); _goPoolDict.Add(key, goPoolObj); } } private class GOPoolObj { private readonly GameObject MyGo; private readonly GameObject GOTemplate; private List<GameObject> _gos; public GOPoolObj(GameObject myGo, GameObject goTemplate) { MyGo = myGo; GOTemplate = goTemplate; _gos = new List<GameObject>(); } public void Destroy() { _gos.Clear(); _gos = null; GameObject.Destroy(MyGo); } public GameObject GetInstance() { if (_gos.Count == 0) { var instance = Instantiate(GOTemplate, MyGo.transform); instance.name = GOTemplate.name + "_0"; _gos.Add(instance); } var go = _gos[0]; _gos.RemoveAt(0); return go; } public void RecycleInstance(GameObject go) { go.name = GOTemplate.name + "_" + _gos.Count; go.transform.SetParent(MyGo.transform); go.transform.localPosition = Vector3.zero; go.transform.localRotation = Quaternion.identity; go.transform.localScale = Vector3.one; go.SetActive(false); _gos.Add(go); } }} |
|