com.alicizax.unity.framework/Editor/GameObjectPool/GameObjectPoolEditor.cs
2026-04-17 21:01:20 +08:00

141 lines
5.5 KiB
C#

using System.Collections.Generic;
using UnityEditor;
using UnityEngine;
namespace AlicizaX
{
[CustomEditor(typeof(GameObjectPoolManager))]
public sealed class GameObjectPoolEditor : UnityEditor.Editor
{
private readonly Dictionary<string, bool> _foldoutState = new Dictionary<string, bool>();
public override void OnInspectorGUI()
{
serializedObject.Update();
DrawDefaultInspector();
serializedObject.ApplyModifiedProperties();
var pool = (GameObjectPoolManager)target;
if (!Application.isPlaying)
{
EditorGUILayout.HelpBox("Enter Play Mode to inspect runtime pool state.", MessageType.Info);
return;
}
if (!pool.showDetailedInfo)
{
return;
}
EditorGUILayout.Space();
DrawRuntimeState(pool);
}
public override bool RequiresConstantRepaint()
{
var pool = target as GameObjectPoolManager;
return pool != null && Application.isPlaying && pool.showDetailedInfo;
}
private void DrawRuntimeState(GameObjectPoolManager poolManager)
{
if (!poolManager.IsReady)
{
EditorGUILayout.HelpBox("GameObjectPool is initializing.", MessageType.Info);
return;
}
List<GameObjectPoolSnapshot> snapshots = poolManager.GetDebugSnapshots();
if (snapshots.Count == 0)
{
EditorGUILayout.HelpBox("No runtime pools have been created yet.", MessageType.Info);
return;
}
for (int i = 0; i < snapshots.Count; i++)
{
DrawSnapshot(snapshots[i]);
}
}
private void DrawSnapshot(GameObjectPoolSnapshot snapshot)
{
if (snapshot == null)
{
return;
}
string key = $"{snapshot.group}|{snapshot.assetPath}";
if (!_foldoutState.ContainsKey(key))
{
_foldoutState[key] = false;
}
EditorGUILayout.BeginVertical("box");
_foldoutState[key] = EditorGUILayout.Foldout(
_foldoutState[key],
$"{snapshot.group} | {snapshot.assetPath} ({snapshot.activeCount}/{snapshot.totalCount})",
true);
if (_foldoutState[key])
{
EditorGUILayout.LabelField("Entry", snapshot.entryName);
EditorGUILayout.LabelField("Loader", snapshot.loaderType.ToString());
EditorGUILayout.LabelField("Overflow Policy", snapshot.overflowPolicy.ToString());
EditorGUILayout.LabelField("Min Retained", snapshot.minRetained.ToString());
EditorGUILayout.LabelField("Soft Capacity", snapshot.softCapacity.ToString());
EditorGUILayout.LabelField("Hard Capacity", snapshot.hardCapacity.ToString());
EditorGUILayout.LabelField("Inactive", snapshot.inactiveCount.ToString());
EditorGUILayout.LabelField("Prefab Loaded", snapshot.prefabLoaded ? "Yes" : "No");
EditorGUILayout.LabelField("Prefab Idle", $"{snapshot.prefabIdleDuration:F1}s");
EditorGUILayout.Space();
EditorGUILayout.LabelField("Acquire", snapshot.acquireCount.ToString());
EditorGUILayout.LabelField("Release", snapshot.releaseCount.ToString());
EditorGUILayout.LabelField("Hit", snapshot.hitCount.ToString());
EditorGUILayout.LabelField("Miss", snapshot.missCount.ToString());
EditorGUILayout.LabelField("Expand", snapshot.expandCount.ToString());
EditorGUILayout.LabelField("Exhausted", snapshot.exhaustedCount.ToString());
EditorGUILayout.LabelField("Auto Recycle", snapshot.autoRecycleCount.ToString());
EditorGUILayout.LabelField("Destroy", snapshot.destroyCount.ToString());
EditorGUILayout.LabelField("Peak Active", snapshot.peakActive.ToString());
EditorGUILayout.LabelField("Peak Total", snapshot.peakTotal.ToString());
if (snapshot.instances.Count > 0)
{
EditorGUILayout.Space();
EditorGUILayout.LabelField("Instances", EditorStyles.boldLabel);
for (int i = 0; i < snapshot.instances.Count; i++)
{
DrawInstance(snapshot.instances[i]);
}
}
}
EditorGUILayout.EndVertical();
EditorGUILayout.Space();
}
private static void DrawInstance(GameObjectPoolInstanceSnapshot instance)
{
if (instance == null)
{
return;
}
EditorGUILayout.BeginHorizontal("box");
EditorGUILayout.BeginVertical();
EditorGUILayout.LabelField(instance.instanceName, EditorStyles.boldLabel);
EditorGUILayout.LabelField("State", instance.isActive ? "Active" : "Inactive");
EditorGUILayout.LabelField("Life", $"{instance.lifeDuration:F1}s");
if (!instance.isActive)
{
EditorGUILayout.LabelField("Idle", $"{instance.idleDuration:F1}s");
}
EditorGUILayout.EndVertical();
EditorGUILayout.ObjectField(instance.gameObject, typeof(GameObject), true, GUILayout.Width(120));
EditorGUILayout.EndHorizontal();
}
}
}