找回密码
 立即注册
查看: 423|回复: 0

Unity中,专用于GameObject的简易对象池

[复制链接]
发表于 2022-3-26 11:21 | 显示全部楼层 |阅读模式
需求

外部传入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);        }    }}
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-9-22 16:39 , Processed in 0.094950 second(s), 25 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表