2026-03-26 10:49:41 +08:00
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using UnityEditor;
|
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
|
|
namespace AlicizaX
|
|
|
|
|
{
|
2026-03-26 16:14:05 +08:00
|
|
|
[CustomEditor(typeof(GameObjectPoolManager))]
|
2026-03-26 10:49:41 +08:00
|
|
|
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();
|
|
|
|
|
|
2026-03-26 16:14:05 +08:00
|
|
|
var pool = (GameObjectPoolManager)target;
|
2026-03-26 10:49:41 +08:00
|
|
|
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()
|
|
|
|
|
{
|
2026-03-26 16:14:05 +08:00
|
|
|
var pool = target as GameObjectPoolManager;
|
2026-03-26 10:49:41 +08:00
|
|
|
return pool != null && Application.isPlaying && pool.showDetailedInfo;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 16:14:05 +08:00
|
|
|
private void DrawRuntimeState(GameObjectPoolManager poolManager)
|
2026-03-26 10:49:41 +08:00
|
|
|
{
|
2026-03-26 16:14:05 +08:00
|
|
|
if (!poolManager.IsReady)
|
2026-03-26 10:49:41 +08:00
|
|
|
{
|
|
|
|
|
EditorGUILayout.HelpBox("GameObjectPool is initializing.", MessageType.Info);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-26 16:14:05 +08:00
|
|
|
List<GameObjectPoolSnapshot> snapshots = poolManager.GetDebugSnapshots();
|
2026-03-26 10:49:41 +08:00
|
|
|
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("Match Mode", snapshot.matchMode.ToString());
|
|
|
|
|
EditorGUILayout.LabelField("Loader", snapshot.loaderType.ToString());
|
|
|
|
|
EditorGUILayout.LabelField("Capacity", snapshot.capacity.ToString());
|
|
|
|
|
EditorGUILayout.LabelField("Inactive", snapshot.inactiveCount.ToString());
|
|
|
|
|
EditorGUILayout.LabelField("Idle Timeout", $"{snapshot.instanceIdleTimeout:F1}s");
|
|
|
|
|
EditorGUILayout.LabelField("Prefab Unload Delay", $"{snapshot.prefabUnloadDelay:F1}s");
|
|
|
|
|
EditorGUILayout.LabelField("Prefab Loaded", snapshot.prefabLoaded ? "Yes" : "No");
|
|
|
|
|
|
|
|
|
|
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");
|
|
|
|
|
if (!instance.isActive)
|
|
|
|
|
{
|
|
|
|
|
EditorGUILayout.LabelField("Idle", $"{instance.idleDuration:F1}s");
|
|
|
|
|
}
|
|
|
|
|
EditorGUILayout.EndVertical();
|
|
|
|
|
EditorGUILayout.ObjectField(instance.gameObject, typeof(GameObject), true, GUILayout.Width(120));
|
|
|
|
|
EditorGUILayout.EndHorizontal();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|