複雑なネストされたオブジェクト プール (5) - オブジェクト プールの一元管理と拡張

【一元管理オブジェクトプール】

オブジェクト プールを統一的に管理するには、初期化、オブジェクトの貸し出し、オブジェクトのリサイクル、オブジェクト プールの増加、オブジェクト プールの削減、およびオブジェクト プールのクリアのメソッドを提供するのが比較的簡単です。

【コード】

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;

namespace Cache
{
    public class ObjectPoolManager
    {
        private static ObjectPoolManager _instance;
        public static ObjectPoolManager Instance
        {
            get
            {
                if (_instance == null)
                    _instance = new ObjectPoolManager();
                return _instance;
            }
        }

        public Dictionary<string, ObjectPoolBase> pools = new Dictionary<string, ObjectPoolBase>();
        private Dictionary<int, string> lentInstance2Object = new Dictionary<int, string>();

        private ObjectPoolAsset objectPoolAsset;

        private string assetPath = "Assets/Resources/ObjectPoolAsset.asset";
#if UNITY_EDITOR
        public void Awake()
        {
            objectPoolAsset = Resources.Load<ObjectPoolAsset>(assetPath);
            if (objectPoolAsset == null)
            {
                objectPoolAsset = ScriptableObject.CreateInstance<ObjectPoolAsset>();
                AssetDatabase.CreateAsset(objectPoolAsset, assetPath);
                AssetDatabase.SaveAssets();
                AssetDatabase.Refresh();
            }
        }
#endif
        public void InitPool()
        {
#if !UNITY_EDITOR
        objectPoolAsset = Resources.Load<ObjectPoolAsset>(assetPath);//不是Editor的情况下如何载入配置,这个可以根据需要自己写
#endif
            foreach (PoolInfo poolInfo in objectPoolAsset.poolInfos)
            {
                AddPool(poolInfo);
            }
        }

        public GameObject LendObjectOut(string poolName, string objectName, Transform parent = null, object[] extradata = null)
        {
            GameObject go = null;
            if(!pools.ContainsKey(poolName))
            {
                Debug.LogWarning("该对象池不存在:" + poolName);
                return null;
            }
            go = pools[poolName].LendObjectOut(objectName, parent, extradata);  
            if(go)
            {
                lentInstance2Object[go.GetInstanceID()] = poolName;
            }
            return go;
        }

        public bool RecycleObject(GameObject go)
        {
            if (go == null)
                return false;

            if (!lentInstance2Object.ContainsKey(go.GetInstanceID()))//表示不是从该对象池中借出的
                return false;
            
            return pools[lentInstance2Object[go.GetInstanceID()]].RecycleObject(go);
        }

        public bool AddPool(PoolInfo poolInfo)
        {
            if (pools.ContainsKey(poolInfo.poolName))
            {
                Debug.LogWarning("已包含该对象池:" + poolInfo.poolName);
                return false;
            }
            switch (poolInfo.poolType)
            {
                case PoolType.Single:
                    pools.Add(poolInfo.poolName, new SingleObjectPool(poolInfo.capacity, poolInfo.poolName, poolInfo.expansionStrategy));
                    break;
                case PoolType.Multi:
                    pools.Add(poolInfo.poolName, new MultiObjectPool(poolInfo));
                    break;
                case PoolType.ObjectType:
                    pools.Add(poolInfo.poolName, new ObjectTypePool(poolInfo));
                    break;
                case PoolType.StageType:
                    pools.Add(poolInfo.poolName, new StageObjectPool(poolInfo));
                    break;
                case PoolType.NONE:
                    Debug.LogWarning("无效的对象池类型:" + poolInfo.poolName);
                    break;
            }
            return true;    
        }

        public bool RemovePool(string poolName)
        {
            if (!pools.ContainsKey(poolName))
            {
                Debug.LogWarning("不存在该对象池:" + poolName);
                return false;
            }

            ObjectPoolBase pool = pools[poolName];
            pools.Remove(poolName);
            pool.Dispose();
            return true;
        }

        public void ClearPool()
        {
            foreach (var item in pools.Values)
            {
                item.Dispose();
            }
            pools.Clear();
            lentInstance2Object.Clear();
        }

    }
}

【拡大】

1. 拡張エディタ: ObjectPoolAsset.asset を自由に編集しても、InitPool() でエラーが報告されないことが保証されています。現在のコードには制御がありません。

2. メモリの削減: オブジェクトがどのプールに属しているかを見つけるために lentInstance2Object に依存します。多層ネストのため、重複が生じます。読み取るオブジェクトにクラスを追加できるため、lentInstance2Object は省略されます。

3. すべて ObjectPoolBase を使用して、さまざまなタイプのオブジェクト プールの自由な組み合わせを実現します

4. AA ベースのロード方法を使用してオブジェクトをロードします

5. 非同期読み込みメソッドを追加する

おすすめ

転載: blog.csdn.net/enternalstar/article/details/125852981