From 14163956e02f6e00c348cfed66d8702c6b27b2ff Mon Sep 17 00:00:00 2001 From: DCFApixels <99481254+DCFApixels@users.noreply.github.com> Date: Sat, 10 May 2025 11:45:24 +0800 Subject: [PATCH] update runtime components inspector --- src/DebugUtils/Editor/EntlongDrawer.cs | 4 +- src/Internal/Editor/EcsGUI.cs | 42 +-- .../Editor/RuntimeComponentsDrawer.cs | 261 ++++++++++++++++-- .../PipelineTemplateUtilityRecordDrawer.cs | 2 +- .../DragonDocs/Editors/DragonDocsWindow.cs | 2 +- 5 files changed, 270 insertions(+), 41 deletions(-) diff --git a/src/DebugUtils/Editor/EntlongDrawer.cs b/src/DebugUtils/Editor/EntlongDrawer.cs index c6eb69f..6d5c95b 100644 --- a/src/DebugUtils/Editor/EntlongDrawer.cs +++ b/src/DebugUtils/Editor/EntlongDrawer.cs @@ -24,7 +24,7 @@ namespace DCFApixels.DragonECS.Unity.Editors bool containsMouse = dropRect.Contains(Event.current.mousePosition); - if(containsMouse && eventType == EventType.Repaint && DragAndDrop.activeControlID == controlID) + if (containsMouse && eventType == EventType.Repaint && DragAndDrop.activeControlID == controlID) { EditorStyles.selectionRect.Draw(dropRect.AddPadding(-1), GUIContent.none, controlID, false, false); } @@ -163,7 +163,7 @@ namespace DCFApixels.DragonECS.Unity.Editors var fields = uniObj.GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (var field in fields) { - if(field.FieldType == typeof(entlong)) + if (field.FieldType == typeof(entlong)) { ent = (entlong)field.GetValue(uniObj); return true; diff --git a/src/Internal/Editor/EcsGUI.cs b/src/Internal/Editor/EcsGUI.cs index 48107a2..58da319 100644 --- a/src/Internal/Editor/EcsGUI.cs +++ b/src/Internal/Editor/EcsGUI.cs @@ -143,10 +143,10 @@ namespace DCFApixels.DragonECS.Unity.Editors private readonly int _value; public IndentLevelScope(int value) { - _value = EditorGUI.indentLevel; - EditorGUI.indentLevel = value; + _value = IndentLevel; + IndentLevel = value; } - public void Dispose() { EditorGUI.indentLevel = _value; } + public void Dispose() { IndentLevel = _value; } } public struct AlignmentScope : IDisposable { @@ -261,7 +261,7 @@ namespace DCFApixels.DragonECS.Unity.Editors public static AlignmentScope SetAlignment(TextAnchor value) => new AlignmentScope(GUI.skin.label, value); public static AlignmentScope SetAlignment(GUIStyle target) => new AlignmentScope(target); public static IndentLevelScope SetIndentLevel(int level) => new IndentLevelScope(level); - public static IndentLevelScope UpIndentLevel() => new IndentLevelScope(EditorGUI.indentLevel + 1); + public static IndentLevelScope UpIndentLevel() => new IndentLevelScope(IndentLevel + 1); public static ContentColorScope SetContentColor(Color value) => new ContentColorScope(value); public static ContentColorScope SetContentColor(Color value, float a) => new ContentColorScope(value.r, value.g, value.b, a); public static ContentColorScope SetContentColor(float r, float g, float b, float a = 1f) => new ContentColorScope(r, g, b, a); @@ -286,12 +286,28 @@ namespace DCFApixels.DragonECS.Unity.Editors internal static readonly Rect HeadIconsRect = new Rect(0f, 0f, 19f, 19f); - public static float EntityBarHeight => EditorGUIUtility.singleLineHeight + 3f; - - private static float indent => (float)EditorGUI.indentLevel * 15f; - private static float indentLevel => EditorGUI.indentLevel; - #region Properties + public static float EntityBarHeight + { + get => EditorGUIUtility.singleLineHeight + 3f; + } + public static float Indent + { + get => EditorGUI.indentLevel * 15f; + } + public static int IndentLevel + { + get => EditorGUI.indentLevel; + set => EditorGUI.indentLevel = value; + } + public static float OneLineHeight + { + get => EditorGUIUtility.singleLineHeight; + } + public static float Spacing + { + get => EditorGUIUtility.standardVerticalSpacing; + } private static ComponentColorMode AutoColorMode { get { return UserSettingsPrefs.instance.ComponentColorMode; } @@ -312,14 +328,6 @@ namespace DCFApixels.DragonECS.Unity.Editors // get { return UserSettingsPrefs.instance.IsFastModeRuntimeComponents; } // set { UserSettingsPrefs.instance.IsFastModeRuntimeComponents = value; } //} - private static float OneLineHeight - { - get => EditorGUIUtility.singleLineHeight; - } - private static float Spacing - { - get => EditorGUIUtility.standardVerticalSpacing; - } #endregion #region enums diff --git a/src/Internal/Editor/RuntimeComponentsDrawer.cs b/src/Internal/Editor/RuntimeComponentsDrawer.cs index ff2aa57..c8bf633 100644 --- a/src/Internal/Editor/RuntimeComponentsDrawer.cs +++ b/src/Internal/Editor/RuntimeComponentsDrawer.cs @@ -69,6 +69,26 @@ namespace DCFApixels.DragonECS.Unity.Editors.X public readonly bool IsCompositeType; public readonly bool IsUnmanaged; + public readonly bool IsLeaf; + public readonly LeafType LeafPropertyType; + public enum LeafType + { + NONE = 0, + Enum, + Bool, + String, + Float, + Double, + Byte, + SByte, + Short, + UShort, + Int, + UInt, + Long, + ULong, + } + public readonly FieldInfoData[] Fields; private RefEditorWrapper[] _wrappers = new RefEditorWrapper[2]; @@ -79,11 +99,71 @@ namespace DCFApixels.DragonECS.Unity.Editors.X public RuntimeComponentReflectionCache(Type type) { - Type = type; ResetWrappers(); IsUnmanaged = UnsafeUtility.IsUnmanaged(type); IsUnityObjectType = typeof(UnityObject).IsAssignableFrom(type); + + LeafPropertyType = LeafType.NONE; + IsLeaf = type.IsPrimitive || type == typeof(string) || type.IsEnum; + + if (IsLeaf) + { + if (type.IsEnum) + { + LeafPropertyType = LeafType.Enum; + } + else if (type == typeof(bool)) + { + LeafPropertyType = LeafType.Bool; + } + else if (type == typeof(string)) + { + LeafPropertyType = LeafType.String; + } + else if (type == typeof(float)) + { + LeafPropertyType = LeafType.Float; + } + else if (type == typeof(double)) + { + LeafPropertyType = LeafType.Double; + } + else if (type == typeof(byte)) + { + LeafPropertyType = LeafType.Byte; + } + else if (type == typeof(sbyte)) + { + LeafPropertyType = LeafType.SByte; + } + else if (type == typeof(short)) + { + LeafPropertyType = LeafType.Short; + } + else if (type == typeof(ushort)) + { + LeafPropertyType = LeafType.UShort; + } + else if (type == typeof(int)) + { + LeafPropertyType = LeafType.Int; + } + else if (type == typeof(uint)) + { + LeafPropertyType = LeafType.UInt; + } + else if (type == typeof(long)) + { + LeafPropertyType = LeafType.Long; + } + else if (type == typeof(ulong)) + { + LeafPropertyType = LeafType.ULong; + } + } + + IsUnitySerializable = IsUnityObjectType || //typeof(Array).IsAssignableFrom(type) || @@ -232,7 +312,7 @@ namespace DCFApixels.DragonECS.Unity.Editors.X } RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name); - if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData)) + if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData, 0)) { cmp.SetRaw(worldID, resultData); } @@ -354,7 +434,7 @@ namespace DCFApixels.DragonECS.Unity.Editors.X RuntimeComponentReflectionCache.FieldInfoData componentInfoData = new RuntimeComponentReflectionCache.FieldInfoData(null, componentType, meta.Name); - if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData)) + if (DrawRuntimeData(ref componentInfoData, UnityEditorUtility.GetLabel(meta.Name), expandMatrix, data, out object resultData, 0)) { pool.SetRaw(entityID, resultData); } @@ -366,8 +446,9 @@ namespace DCFApixels.DragonECS.Unity.Editors.X #region draw data - private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData) + private bool DrawRuntimeData(ref RuntimeComponentReflectionCache.FieldInfoData fieldInfoData, GUIContent label, ExpandMatrix expandMatrix, object data, out object outData, int depth) { + const int DEPTH_MAX = 64; outData = data; Type type = data == null ? typeof(void) : data.GetType(); @@ -379,14 +460,19 @@ namespace DCFApixels.DragonECS.Unity.Editors.X EditorGUILayout.TextField(label, "Null"); return false; } + if (depth >= DEPTH_MAX || cache == null) + { + EditorGUILayout.TextField(label, "error"); + return false; + } bool isUnityObjectType = cache.IsUnityObjectType; ref bool isExpanded = ref expandMatrix.Down(); bool changed = false; - if (cache.IsUnitySerializable == false && cache.IsCompositeType) { + GUILayout.Space(EcsGUI.Spacing); var foldoutStyle = EditorStyles.foldout; Rect rect = GUILayoutUtility.GetRect(label, foldoutStyle); rect.xMin += EcsGUI.Indent; @@ -397,17 +483,14 @@ namespace DCFApixels.DragonECS.Unity.Editors.X { using (EcsGUI.UpIndentLevel()) { - if (cache != null) + for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++) { - for (int j = 0, jMax = cache.Fields.Length; j < jMax; j++) + var field = cache.Fields[j]; + if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData, depth + 1)) { - var field = cache.Fields[j]; - if (DrawRuntimeData(ref field, UnityEditorUtility.GetLabel(field.UnityFormatName), expandMatrix, field.FieldInfo.GetValue(data), out object fieldData)) - { - field.FieldInfo.SetValue(data, fieldData); - outData = data; - changed = true; - } + field.FieldInfo.SetValue(data, fieldData); + outData = data; + changed = true; } } } @@ -451,15 +534,154 @@ namespace DCFApixels.DragonECS.Unity.Editors.X try { - if (cache.IsCompositeType && fieldInfoData.IsPassToUnitySerialize) + if (fieldInfoData.IsPassToUnitySerialize) { - wrapper.SO.Update(); - wrapper.IsExpanded = isExpanded; - EditorGUILayout.PropertyField(wrapper.Property, label, true); + if (cache.IsCompositeType) + { + wrapper.SO.Update(); + wrapper.IsExpanded = isExpanded; + EditorGUILayout.PropertyField(wrapper.Property, label, true); + if (GUI.changed) + { + wrapper.SO.ApplyModifiedProperties(); + } + } + else if (cache.IsLeaf) + { + var eventType = Event.current.type; + switch (cache.LeafPropertyType) + { + //case RuntimeComponentReflectionCache.LeafType.Enum: + // break; + case RuntimeComponentReflectionCache.LeafType.Bool: + if (eventType != EventType.Layout) + { + wrapper.data = EditorGUILayout.Toggle(label, (bool)data); + } + else + { + EditorGUILayout.Toggle(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.String: + if (eventType != EventType.Layout) + { + wrapper.data = EditorGUILayout.TextField(label, (string)data); + } + else + { + EditorGUILayout.TextField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.Float: + if (eventType != EventType.Layout) + { + wrapper.data = EditorGUILayout.FloatField(label, (float)data); + } + else + { + EditorGUILayout.FloatField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.Double: + if (eventType != EventType.Layout) + { + wrapper.data = EditorGUILayout.DoubleField(label, (double)data); + } + else + { + EditorGUILayout.DoubleField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.Byte: + if (eventType != EventType.Layout) + { + wrapper.data = (byte)EditorGUILayout.IntField(label, (byte)data); + } + else + { + EditorGUILayout.IntField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.SByte: + if (eventType != EventType.Layout) + { + wrapper.data = (sbyte)EditorGUILayout.IntField(label, (sbyte)data); + } + else + { + EditorGUILayout.IntField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.Short: + if (eventType != EventType.Layout) + { + wrapper.data = (short)EditorGUILayout.IntField(label, (short)data); + } + else + { + EditorGUILayout.IntField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.UShort: + if (eventType != EventType.Layout) + { + wrapper.data = (ushort)EditorGUILayout.IntField(label, (ushort)data); + } + else + { + EditorGUILayout.IntField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.Int: + if (eventType != EventType.Layout) + { + wrapper.data = (int)EditorGUILayout.IntField(label, (int)data); + } + else + { + EditorGUILayout.IntField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.UInt: + if (eventType != EventType.Layout) + { + wrapper.data = (uint)EditorGUILayout.IntField(label, (int)(uint)data); + } + else + { + EditorGUILayout.IntField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.Long: + if (eventType != EventType.Layout) + { + wrapper.data = EditorGUILayout.LongField(label, (long)data); + } + else + { + EditorGUILayout.LongField(label, default); + } + break; + case RuntimeComponentReflectionCache.LeafType.ULong: + if (eventType != EventType.Layout) + { + wrapper.data = (ulong)EditorGUILayout.LongField(label, (long)(ulong)data); + } + else + { + EditorGUILayout.LongField(label, default); + } + break; + default: + EditorGUILayout.LabelField(label); + break; + } + } + } else { - //EcsGUI. EditorGUILayout.LabelField(label); } } @@ -474,7 +696,6 @@ namespace DCFApixels.DragonECS.Unity.Editors.X { if (EditorGUI.EndChangeCheck()) { - wrapper.SO.ApplyModifiedProperties(); outData = wrapper.Data; changed = true; } diff --git a/src/Templates/PipelineTemplate/Editor/PipelineTemplateUtilityRecordDrawer.cs b/src/Templates/PipelineTemplate/Editor/PipelineTemplateUtilityRecordDrawer.cs index 7ef4a0f..aea8d46 100644 --- a/src/Templates/PipelineTemplate/Editor/PipelineTemplateUtilityRecordDrawer.cs +++ b/src/Templates/PipelineTemplate/Editor/PipelineTemplateUtilityRecordDrawer.cs @@ -21,7 +21,7 @@ namespace DCFApixels.DragonECS.Unity.Editors } } - using (EcsGUI.SetIndentLevel(IsArrayElement ? EditorGUI.indentLevel : EditorGUI.indentLevel + 1)) + using (EcsGUI.SetIndentLevel(IsArrayElement ? EcsGUI.IndentLevel : EcsGUI.IndentLevel + 1)) { Rect subPosition = position; int depth = -1; diff --git a/src/Tools/DragonDocs/Editors/DragonDocsWindow.cs b/src/Tools/DragonDocs/Editors/DragonDocsWindow.cs index a34a625..37fc775 100644 --- a/src/Tools/DragonDocs/Editors/DragonDocsWindow.cs +++ b/src/Tools/DragonDocs/Editors/DragonDocsWindow.cs @@ -363,7 +363,7 @@ namespace DCFApixels.DragonECS.Unity.Docs.Editors if (_searchingSample.Length == 0) { - EditorGUI.indentLevel = groupInfo.Depth; + EcsGUI.IndentLevel = groupInfo.Depth; } GUIContent label = UnityEditorUtility.GetLabel(_searchingSample.Length == 0 ? groupInfo.Name : groupInfo.Path);