hch
2025-07-28 b653fb8a1b763a328f73c5a9d3845bb54a003bb0
0312 对象池管理,备份代码
1个文件已修改
169 ■■■■ 已修改文件
Main/Core/ResModule/GameObjectPoolManager.cs 169 ●●●● 补丁 | 查看 | 原始文档 | blame | 历史
Main/Core/ResModule/GameObjectPoolManager.cs
@@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using UnityEngine;
using System;
@@ -15,6 +15,9 @@
    private List<int> dontDestoryGoInstIDList = null;
    private Transform m_TargetContainer;
    //需要动态卸载的预制体,例如切换场景时
    public List<GameObject> needDestroyPrefabList = new List<GameObject>();
    public void Initialize()
    {
@@ -108,17 +111,17 @@
        return RequestPool(prefab).Request();
    }
    //特定情况下需要动态卸载的,如切换场景时
    public void UnLoadAll(bool force = false)
    {
        List<int> _removeList = new List<int>();
        foreach (var _pool in m_PoolDict.Values)
        {
            // if (GAMgr.Instance.needDestroyPrefabList.Contains(_pool.Prefab))
            // {
            if (needDestroyPrefabList.Contains(_pool.Prefab))
            {
                _pool.Clear();
                _removeList.Add(_pool.PrefabInstanceId);
            // }
            }
        }
        for (int i = 0; i < _removeList.Count; ++i)
@@ -137,13 +140,16 @@
                return m_Prefab;
            }
        }
        //预制体实例id,用于检索池
        public int PrefabInstanceId
        {
            get; private set;
        }
        public List<GameObject> m_ActiveList = null;
        private List<GameObject> m_FreeList = null;
        public HashSet<GameObject> m_ActiveHashSet = new HashSet<GameObject>();
        private Queue<GameObject> m_FreeQueue = null;
        private int Pool_FreeList_Warning_Threshold = 8;
        Action<GameObject> releaseCallBack;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
@@ -159,8 +165,8 @@
        {
            m_Prefab = prefab;
            PrefabInstanceId = m_Prefab.GetInstanceID();
            m_ActiveList = new List<GameObject>();
            m_FreeList = new List<GameObject>();
            m_ActiveHashSet = new HashSet<GameObject>();
            m_FreeQueue = new Queue<GameObject>();
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            m_DebugContainer = new GameObject(prefab.name).transform;
@@ -188,11 +194,17 @@
            for (int i = 0; i < count; ++i)
            {
                _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                m_FreeList.Add(_go);
                m_FreeQueue.Enqueue(_go);
                _go.transform.SetParent(Instance.m_TargetContainer);
                _go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                // 检查空闲列表数量是否超过阈值
                if (m_FreeList.Count > Pool_FreeList_Warning_Threshold)
                {
                    Debug.LogWarning($"GameObjectPool {m_Prefab.name} 的空闲对象数量 ({m_FreeList.Count}) 超过阈值 ({Pool_FreeList_Warning_Threshold}),请检查是否需要清理。");
                }
                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
                _debugItem.transform.SetParent(m_DebugFree);
@@ -212,34 +224,26 @@
        {
            GameObject _go = null;
            while (m_FreeList.Count > 0)
            if (m_FreeQueue.Count > 0)
            {
                if (m_FreeList[0] != null)
                {
                    _go = m_FreeList[0];
                _go = m_FreeQueue.Dequeue();
                    m_ActiveList.Add(_go);
                    m_FreeList.RemoveAt(0);
                m_ActiveHashSet.Add(_go);
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                    if (Instance.m_DebugInstIDDict.ContainsKey(_go.GetInstanceID()))
                    {
                        DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                        _debugItem.transform.SetParent(m_DebugActive);
                    }
#endif
                    break;
                }
                else
                if (Instance.m_DebugInstIDDict.ContainsKey(_go.GetInstanceID()))
                {
                    m_FreeList.RemoveAt(0);
                    DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                    _debugItem.transform.SetParent(m_DebugActive);
                }
#endif
            }
            if (_go == null)
            {
                _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                m_ActiveList.Add(_go);
                m_ActiveHashSet.Add(_go);
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
@@ -261,20 +265,19 @@
            {
                return;
            }
            if (m_ActiveList.Contains(go))
            {
                m_ActiveList.Remove(go);
            }
            if (m_FreeList.Contains(go))
            {
                return;
            }
            m_ActiveHashSet.Remove(go);
            m_FreeList.Add(go);
            m_FreeQueue.Enqueue(go);
            go.transform.SetParent(Instance.m_TargetContainer);
            go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            // 检查空闲列表数量是否超过阈值
            if (m_FreeList.Count > Pool_FreeList_Warning_Threshold)
            {
                Debug.LogWarning($"GameObjectPool {m_Prefab.name} 的空闲对象数量 ({m_FreeList.Count}) 超过阈值 ({Pool_FreeList_Warning_Threshold}),请检查是否需要清理。");
            }
            if (Instance.m_DebugInstIDDict.ContainsKey(go.GetInstanceID()))
            {
                DebugItem _debugItem = Instance.m_DebugInstIDDict[go.GetInstanceID()];
@@ -290,75 +293,75 @@
        public void ReleaseAll()
        {
            for (int i = m_ActiveList.Count - 1; i >= 0; i--)
            //释放 m_ActiveHashSet中 的GameObject,排除
            foreach (GameObject go in m_ActiveHashSet)
            {
                var _go = m_ActiveList[i];
                m_ActiveList.Remove(_go);
                if (!m_FreeList.Contains(_go))
                if (go != null)
                {
                    m_FreeList.Add(_go);
                }
                    m_FreeQueue.Enqueue(go);
                    go.transform.SetParent(Instance.m_TargetContainer);
                    go.transform.position = Constants.Special_Hide_Position;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
                _debugItem.transform.SetParent(m_DebugFree);
                    if (Instance.m_DebugInstIDDict.ContainsKey(go.GetInstanceID()))
                    {
                        DebugItem _debugItem = Instance.m_DebugInstIDDict[go.GetInstanceID()];
                        _debugItem.transform.SetParent(m_DebugFree);
                    }
#endif
                _go.transform.SetParent(Instance.m_TargetContainer);
                _go.transform.position = Constants.Special_Hide_Position;
                if (releaseCallBack != null)
                {
                    releaseCallBack(_go);
                    if (releaseCallBack != null)
                    {
                        releaseCallBack(go);
                    }
                }
            }
            m_ActiveHashSet.Clear();
        }
        public void Clear()
        {
            for (int i = m_ActiveList.Count - 1; i >= 0; --i)
            foreach (GameObject go in m_ActiveHashSet)
            {
                if (m_ActiveList[i] == null
                || Instance.dontDestoryGoInstIDList.Contains(m_ActiveList[i].GetInstanceID()))
                    continue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(Instance.m_DebugInstIDDict[m_ActiveList[i].GetInstanceID()].gameObject);
#endif
                Destroy(m_ActiveList[i]);
                m_ActiveList.RemoveAt(i);
            }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_ActiveList.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个活跃对象. ", m_Prefab.name, m_ActiveList.Count);
                for (int i = 0; i < m_ActiveList.Count; ++i)
                if (go != null)
                {
                    Debug.LogWarningFormat(" |-- {0}", m_ActiveList[i].name);
                    if (!Instance.dontDestoryGoInstIDList.Contains(go.GetInstanceID()))
                    {
                        m_ActiveHashSet.Remove(go);
                        Destroy(go);
                    }
                }
            }
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_ActiveHashSet.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个活跃对象. ", m_Prefab.name, m_ActiveHashSet.Count);
            }
#endif
            for (int i = m_FreeList.Count - 1; i >= 0; --i)
            Queue<GameObject> tempQueue = new Queue<GameObject>();
            while (m_FreeQueue.Count > 0)
            {
                if (m_FreeList[i] == null
                 || Instance.dontDestoryGoInstIDList.Contains(m_FreeList[i].GetInstanceID()))
                    continue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
                Destroy(Instance.m_DebugInstIDDict[m_FreeList[i].GetInstanceID()].gameObject);
#endif
                Destroy(m_FreeList[i]);
                m_FreeList.RemoveAt(i);
                GameObject obj = m_FreeQueue.Dequeue();
                if (Instance.dontDestoryGoInstIDList.Contains(obj.GetInstanceID()))
                    tempQueue.Enqueue(obj);
                else
                    Destroy(obj);
            }
            m_FreeQueue = tempQueue;
#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
            if (m_FreeList.Count != 0)
            {
                Debug.LogWarningFormat("{0} 池清理后, 还有 {1} 个空闲对象. ", m_Prefab.name, m_FreeList.Count);
                for (int i = 0; i < m_FreeList.Count; ++i)
                {
                    Debug.LogWarningFormat(" |-- {0}", m_FreeList[i].name);
                }
                // for (int i = 0; i < m_FreeList.Count; ++i)
                // {
                //     Debug.LogWarningFormat(" |-- {0}", m_FreeList[i].name);
                // }
            }
#endif
            if (IsEmpty())
@@ -372,13 +375,13 @@
            if (!string.IsNullOrEmpty(assetBundleName) && !string.IsNullOrEmpty(assetName))
            {
                ResManager.Instance.UnloadAsset(assetBundleName, assetName);
                ResManager.Instance.UnloadAssetBundle(assetBundleName, true, false);
                // ResManager.Instance.UnloadAssetBundle(assetBundleName, true, false);
            }
        }
        public bool IsEmpty()
        {
            return m_ActiveList.Count == 0 && m_FreeList.Count == 0;
            return m_ActiveHashSet.Count == 0 && m_FreeQueue.Count == 0;
        }
    }
}