From aa72688fbfcba5cf8d90a7b34700bbe1f9ebee12 Mon Sep 17 00:00:00 2001
From: hch <305670599@qq.com>
Date: 星期四, 11 九月 2025 22:26:52 +0800
Subject: [PATCH] 0312 自动战斗打BOSS暂停

---
 Main/Core/ResModule/GameObjectPoolManager.cs |  296 +++++++++++++++++++++++++++++++++++++++++++++++------------
 1 files changed, 235 insertions(+), 61 deletions(-)

diff --git a/Main/Core/ResModule/GameObjectPoolManager.cs b/Main/Core/ResModule/GameObjectPoolManager.cs
index eac955c..942a36e 100644
--- a/Main/Core/ResModule/GameObjectPoolManager.cs
+++ b/Main/Core/ResModule/GameObjectPoolManager.cs
@@ -1,20 +1,167 @@
 using System.Collections.Generic;
 using UnityEngine;
 using System;
+using Cysharp.Threading.Tasks;
+using System.Linq;
 
+#if UNITY_EDITOR
+using UnityEngine.Profiling;
+#endif
 
 
 public class GameObjectPoolManager : SingletonMonobehaviour<GameObjectPoolManager>
 {
 #if UNITY_EDITOR
-    private Dictionary<int, DebugItem> m_DebugInstIDDict = null;
+    private bool m_ShowDebugPanel = false;
+    private Vector2 m_ScrollPosition = Vector2.zero;
+
+    
+    private void OnGUI()
+    {
+        if (!m_ShowDebugPanel) return;
+
+        GUILayout.BeginArea(new Rect(10, 10, 400, 600));
+        GUILayout.BeginVertical("Box");
+        m_ScrollPosition = GUILayout.BeginScrollView(m_ScrollPosition, GUILayout.Width(380), GUILayout.Height(580));
+
+        GUILayout.Label("瀵硅薄姹犺皟璇曢潰鏉�", GUILayout.Height(30));
+        LogPoolMemoryUsage();
+        GUILayout.Space(10);
+
+        foreach (var poolEntry in m_PoolDict)
+        {
+            int prefabInstanceId = poolEntry.Key;
+            GameObjectPool pool = poolEntry.Value;
+
+            GUILayout.BeginVertical("Box");
+            GUILayout.Label($"姹犲悕绉�: {pool.Prefab.name}");
+            GUILayout.Label($"娲昏穬瀵硅薄鏁�: {pool.m_ActiveHashSet.Count}");
+            GUILayout.Label($"绌洪棽瀵硅薄鏁�: {pool.m_FreeQueue.Count}");
+            int count = m_PoolUsageFrequency.TryGetValue(prefabInstanceId, out int frequency) ? frequency : 0;
+            GUILayout.Label($"浣跨敤棰戠巼: {count}");
+            GUILayout.EndVertical();
+            GUILayout.Space(5);
+        }
+
+        GUILayout.EndScrollView();
+        GUILayout.EndVertical();
+        GUILayout.EndArea();
+    }
+
+    [UnityEditor.MenuItem("Tools/瀵硅薄姹�/鏄剧ず璋冭瘯闈㈡澘")]
+    private static void ToggleDebugPanel()
+    {
+        if (Instance != null)
+        {
+            Instance.m_ShowDebugPanel = !Instance.m_ShowDebugPanel;
+        }
+    }
+
+    public void LogPoolMemoryUsage()
+    {
+        long totalMemory = 0;
+        long totalFreeMemory = 0;
+        var prefabMemoryDict = new Dictionary<string, long>();
+
+        foreach (var poolEntry in m_PoolDict)
+        {
+            int prefabInstanceId = poolEntry.Key;
+            GameObjectPool pool = poolEntry.Value;
+            string prefabName = pool.Prefab.name;
+            long prefabMemory = 0;
+            long freeMemory = 0;
+
+            // 璁$畻娲昏穬瀵硅薄鐨勫唴瀛樺崰鐢�
+            foreach (var gameObject in pool.m_ActiveHashSet)
+            {
+                if (gameObject != null)
+                {
+                    long memory = Profiler.GetRuntimeMemorySizeLong(gameObject);
+                    prefabMemory += memory;
+                }
+            }
+
+            // 璁$畻绌洪棽瀵硅薄鐨勫唴瀛樺崰鐢�
+            foreach (var gameObject in pool.m_FreeQueue)
+            {
+                if (gameObject != null)
+                {
+                    long memory = Profiler.GetRuntimeMemorySizeLong(gameObject);
+                    prefabMemory += memory;
+                    freeMemory += memory;
+                }
+            }
+
+            totalMemory += prefabMemory;
+            totalFreeMemory += freeMemory;
+            prefabMemoryDict[prefabName] = prefabMemory;
+        }
+
+        // 鎸夊唴瀛樺崰鐢ㄦ帓搴�
+        var sortedPrefabs = prefabMemoryDict.OrderByDescending(kv => kv.Value).Take(3).ToList();
+
+        GUILayout.Label($"鎬诲唴瀛樺崰鐢�: {totalMemory / 1024} KB", GUILayout.Height(30));
+        GUILayout.Label($"绌洪棽鍐呭瓨鍗犵敤: {totalFreeMemory / 1024} KB", GUILayout.Height(30));
+        GUILayout.Label("鍗犵敤鏈�楂樼殑鍓�3棰勫埗浣撳悕:", GUILayout.Height(30));
+        foreach (var prefabInstance in sortedPrefabs)
+        {
+            GUILayout.BeginHorizontal("Box");
+            GUILayout.Label($"{prefabInstance.Key}({prefabInstance.Value / 1024} KB)", GUILayout.Height(25));
+            GUILayout.EndHorizontal();
+        }
+
+    }
+
+
 #endif
+    // 姹犵粺璁℃暟鎹�
+    public Dictionary<int, PoolStats> PoolStatistics { get; private set; } = new Dictionary<int, PoolStats>();
+
+    public class PoolStats
+    {
+        public int TotalObjects { get; set; }
+        public int ActiveObjects { get; set; }
+        public int FreeObjects { get; set; }
+        public int UsageFrequency { get; set; }
+    }
+
+    // 鏇存柊姹犵粺璁℃暟鎹�
+    private void UpdatePoolStats()
+    {
+        if (m_PoolDict == null)
+            return;
+            
+        foreach (var poolEntry in m_PoolDict)
+        {
+            int prefabInstanceId = poolEntry.Key;
+            GameObjectPool pool = poolEntry.Value;
+
+            if (!PoolStatistics.ContainsKey(prefabInstanceId))
+            {
+                PoolStatistics[prefabInstanceId] = new PoolStats();
+            }
+
+            PoolStats stats = PoolStatistics[prefabInstanceId];
+            stats.TotalObjects = pool.m_ActiveHashSet.Count + pool.m_FreeQueue.Count;
+            stats.ActiveObjects = pool.m_ActiveHashSet.Count;
+            stats.FreeObjects = pool.m_FreeQueue.Count;
+            stats.UsageFrequency = m_PoolUsageFrequency.TryGetValue(prefabInstanceId, out int frequency) ? frequency : 0;
+        }
+    }
+
+
     private Dictionary<int, GameObjectPool> m_PoolDict = null;
 
     // 涓嶉渶瑕侀攢姣佺殑瀵硅薄鍒楄〃
     private List<int> dontDestoryGoInstIDList = null;
 
     private Transform m_TargetContainer;
+
+    // 瀹氭湡妫�鏌ユ睜鐨勬椂闂撮棿闅旓紙绉掞級
+    private float m_PoolCheckInterval = 600f;
+
+    // 璁板綍姣忎釜姹犵殑浣跨敤棰戠巼
+    private Dictionary<int, int> m_PoolUsageFrequency = new Dictionary<int, int>();
 
     //闇�瑕佸姩鎬佸嵏杞界殑棰勫埗浣擄紝渚嬪鍒囨崲鍦烘櫙鏃�
     public List<GameObject> needDestroyPrefabList = new List<GameObject>();
@@ -37,12 +184,40 @@
             dontDestoryGoInstIDList = new List<int>();
         }
 
-#if UNITY_EDITOR
-        if (m_DebugInstIDDict == null)
+        // 鍚姩瀹氭湡妫�鏌ユ睜鐨勫崗绋�
+        CheckPoolUsage();
+    }
+
+    private async UniTask CheckPoolUsage()
+    {
+        while (true)
         {
-            m_DebugInstIDDict = new Dictionary<int, DebugItem>();
+            await UniTask.Delay(TimeSpan.FromSeconds(m_PoolCheckInterval));
+
+            foreach (var poolEntry in m_PoolDict)
+            {
+                int prefabInstanceId = poolEntry.Key;
+                GameObjectPool pool = poolEntry.Value;
+
+                // 濡傛灉姹犵殑浣跨敤棰戠巼浣庝簬闃堝�硷紝鍑忓皯姹犵殑澶у皬
+                if (m_PoolUsageFrequency.TryGetValue(prefabInstanceId, out int usageCount) && usageCount < 5)
+                {
+                    // 淇濈暀鑷冲皯涓�涓璞★紝閬垮厤棰戠箒鍒涘缓鍜岄攢姣�
+                    int targetSize = Mathf.Max(1, pool.m_FreeQueue.Count / 2);
+                    while (pool.m_FreeQueue.Count > targetSize)
+                    {
+                        GameObject obj = pool.m_FreeQueue.Dequeue();
+                        if (!dontDestoryGoInstIDList.Contains(obj.GetInstanceID()))
+                        {
+                            Destroy(obj);
+                        }
+                    }
+                }
+
+                // 閲嶇疆浣跨敤棰戠巼
+                m_PoolUsageFrequency[prefabInstanceId] = 0;
+            }
         }
-#endif
     }
 
     public void AddDontDestroyGoInstID(int id)
@@ -68,12 +243,26 @@
         return false;
     }
 
+    /// <summary>
+    /// 浼犲叆鐨勪负棰勫埗浣擄紝鑰岄潪缁勪欢锛屽惁鍒欎細瀵艰嚧GetInstanceID绠$悊娣蜂贡锛屾瘡娆″疄渚嬪寲閮戒細鏀瑰彉
+    /// </summary>
+    /// <param name="prefab"></param>
+    /// <returns></returns>
     public GameObjectPool RequestPool(GameObject prefab)
     {
         if (prefab == null)
         {
             return null;
         }
+
+#if UNITY_EDITOR
+        if (UnityEditor.PrefabUtility.GetPrefabAssetType(prefab) == UnityEditor.PrefabAssetType.NotAPrefab)
+        {
+            Debug.LogError($"{prefab.name}涓嶆槸涓�涓鍒朵綋锛�");
+            return null;
+        }
+#endif
+
 
         int _prefabInstanceId = prefab.GetInstanceID();
 
@@ -108,8 +297,16 @@
             return null;
         }
 
+#if UNITY_EDITOR
+        if (UnityEditor.PrefabUtility.GetPrefabAssetType(prefab) == UnityEditor.PrefabAssetType.NotAPrefab)
+        {
+            Debug.LogError($"{prefab.name}涓嶆槸涓�涓鍒朵綋锛�");
+            return null;
+        }
+#endif
         return RequestPool(prefab).Request();
     }
+
 
     //鐗瑰畾鎯呭喌涓嬮渶瑕佸姩鎬佸嵏杞界殑锛屽鍒囨崲鍦烘櫙鏃�
     public void UnLoadAll(bool force = false)
@@ -148,15 +345,11 @@
         }
 
         public HashSet<GameObject> m_ActiveHashSet = new HashSet<GameObject>();
-        private Queue<GameObject> m_FreeQueue = null;
-        private int Pool_FreeList_Warning_Threshold = 8;
+        public Queue<GameObject> m_FreeQueue = null;
+        private int Pool_FreeList_Warning_Threshold = 10;    //褰撶┖闂插璞¢珮浜庢鍊兼椂锛屼細杩涜鏃ュ織杈撳嚭鎻愰啋
 
         Action<GameObject> releaseCallBack;
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
-        private Transform m_DebugContainer;
-        private Transform m_DebugActive;
-        private Transform m_DebugFree;
-#endif
+
 
         public string assetBundleName;
         public string assetName;
@@ -168,14 +361,6 @@
             m_ActiveHashSet = new HashSet<GameObject>();
             m_FreeQueue = new Queue<GameObject>();
 
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
-            m_DebugContainer = new GameObject(prefab.name).transform;
-            m_DebugActive = new GameObject("Active").transform;
-            m_DebugFree = new GameObject("Free").transform;
-            m_DebugActive.SetParent(m_DebugContainer);
-            m_DebugFree.SetParent(m_DebugContainer);
-            m_DebugContainer.SetParent(Instance.transform);
-#endif
         }
 
         public void AddReleaseListener(Action<GameObject> _callBack)
@@ -199,17 +384,12 @@
                 _go.transform.position = Constants.Special_Hide_Position;
 
 
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
+#if UNITY_EDITOR
                 // 妫�鏌ョ┖闂插垪琛ㄦ暟閲忔槸鍚﹁秴杩囬槇鍊�
-                if (m_FreeList.Count > Pool_FreeList_Warning_Threshold)
+                if (m_FreeQueue.Count > Pool_FreeList_Warning_Threshold)
                 {
-                    Debug.LogWarning($"GameObjectPool {m_Prefab.name} 鐨勭┖闂插璞℃暟閲� ({m_FreeList.Count}) 瓒呰繃闃堝�� ({Pool_FreeList_Warning_Threshold})锛岃妫�鏌ユ槸鍚﹂渶瑕佹竻鐞嗐��");
+                    Debug.LogWarning($"GameObjectPool {m_Prefab.name} 鐨勭┖闂插璞℃暟閲� ({m_FreeQueue.Count}) 瓒呰繃闃堝�� ({Pool_FreeList_Warning_Threshold})锛岃妫�鏌ユ槸鍚﹂渶瑕佹竻鐞嗐��");
                 }
-
-                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
-                _debugItem.transform.SetParent(m_DebugFree);
-                _debugItem.target = _go;
-                Instance.m_DebugInstIDDict[_go.GetInstanceID()] = _debugItem;
 #endif
                 var animator = _go.GetComponent<Animator>();
                 if (animator != null)
@@ -230,13 +410,16 @@
 
                 m_ActiveHashSet.Add(_go);
 
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
-                if (Instance.m_DebugInstIDDict.ContainsKey(_go.GetInstanceID()))
+                // 缁熻姹犵殑浣跨敤棰戠巼
+                if (Instance.m_PoolUsageFrequency.ContainsKey(m_Prefab.GetInstanceID()))
                 {
-                    DebugItem _debugItem = Instance.m_DebugInstIDDict[_go.GetInstanceID()];
-                    _debugItem.transform.SetParent(m_DebugActive);
+                    Instance.m_PoolUsageFrequency[m_Prefab.GetInstanceID()]++;
                 }
-#endif
+                else
+                {
+                    Instance.m_PoolUsageFrequency[m_Prefab.GetInstanceID()] = 1;
+                }
+
             }
 
 
@@ -245,19 +428,17 @@
                 _go = Instantiate(m_Prefab, Constants.Special_Hide_Position, Quaternion.identity);
                 m_ActiveHashSet.Add(_go);
 
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
-                DebugItem _debugItem = new GameObject(_go.GetInstanceID().ToString()).AddMissingComponent<DebugItem>();
-                _debugItem.transform.SetParent(m_DebugActive);
-                _debugItem.target = _go;
-                Instance.m_DebugInstIDDict[_go.GetInstanceID()] = _debugItem;
-#endif
             }
 
             _go.transform.SetParent(null);
             _go.transform.localScale = Vector3.one;
 
+            // 鏇存柊姹犵粺璁℃暟鎹�
+            Instance.UpdatePoolStats();
+
             return _go;
         }
+
 
         public void Release(GameObject go)
         {
@@ -269,19 +450,15 @@
 
             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 UNITY_EDITOR
             // 妫�鏌ョ┖闂插垪琛ㄦ暟閲忔槸鍚﹁秴杩囬槇鍊�
-            if (m_FreeList.Count > Pool_FreeList_Warning_Threshold)
+            if (m_FreeQueue.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()];
-                _debugItem.transform.SetParent(m_DebugFree);
+                Debug.LogWarning($"GameObjectPool {m_Prefab.name} 鐨勭┖闂插璞℃暟閲� ({m_FreeQueue.Count}) 瓒呰繃闃堝�� ({Pool_FreeList_Warning_Threshold})锛岃妫�鏌ユ槸鍚﹂渶瑕佹竻鐞嗐��");
             }
 #endif
 
@@ -289,6 +466,9 @@
             {
                 releaseCallBack(go);
             }
+
+            // 鏇存柊姹犵粺璁℃暟鎹�
+            Instance.UpdatePoolStats();
         }
 
         public void ReleaseAll()
@@ -302,13 +482,6 @@
                     go.transform.SetParent(Instance.m_TargetContainer);
                     go.transform.position = Constants.Special_Hide_Position;
 
-#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_DebugFree);
-                    }
-#endif
                     if (releaseCallBack != null)
                     {
                         releaseCallBack(go);
@@ -317,6 +490,9 @@
                 
             }
             m_ActiveHashSet.Clear();
+
+            // 鏇存柊姹犵粺璁℃暟鎹�
+            Instance.UpdatePoolStats();
         }
 
         public void Clear()
@@ -335,7 +511,7 @@
                 
             }
 
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
+#if UNITY_EDITOR
             if (m_ActiveHashSet.Count != 0)
             {
                 Debug.LogWarningFormat("{0} 姹犳竻鐞嗗悗, 杩樻湁 {1} 涓椿璺冨璞�. ", m_Prefab.name, m_ActiveHashSet.Count);
@@ -354,10 +530,10 @@
             m_FreeQueue = tempQueue;
 
 
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
-            if (m_FreeList.Count != 0)
+#if UNITY_EDITOR
+            if (m_FreeQueue.Count != 0)
             {
-                Debug.LogWarningFormat("{0} 姹犳竻鐞嗗悗, 杩樻湁 {1} 涓┖闂插璞�. ", m_Prefab.name, m_FreeList.Count);
+                Debug.LogWarningFormat("{0} 姹犳竻鐞嗗悗, 杩樻湁 {1} 涓┖闂插璞�. ", m_Prefab.name, m_FreeQueue.Count);
                 // for (int i = 0; i < m_FreeList.Count; ++i)
                 // {
                 //     Debug.LogWarningFormat(" |-- {0}", m_FreeList[i].name);
@@ -367,9 +543,7 @@
             if (IsEmpty())
             {
                 m_Prefab = null;
-#if UNITY_EDITOR && !UNITY_ANDROID && !UNITY_IOS
-                Destroy(m_DebugContainer.gameObject);
-#endif
+
             }
 
             if (!string.IsNullOrEmpty(assetBundleName) && !string.IsNullOrEmpty(assetName))

--
Gitblit v1.8.0