com.alicizax.unity.animatio.../Editor/Inspector/GraphInspector.cs

184 lines
5.8 KiB
C#
Raw Normal View History

2025-02-07 16:05:13 +08:00
using System;
2025-11-18 11:27:53 +08:00
using System.Reflection;
2025-02-07 16:05:13 +08:00
using AlicizaX.AnimationFlow.Runtime;
using UnityEditor;
using UnityEngine;
using UnityEngine.UIElements;
namespace AlicizaX.AnimationFlow.Editor
{
public class GraphInspector : VisualElement
{
2025-11-18 11:27:53 +08:00
private ActionNode currentActionNode;
private NodeView currentNodeView;
2025-02-07 16:05:13 +08:00
public void DrawNode(NodeView nodeView)
{
Clear();
2025-11-18 11:27:53 +08:00
if (nodeView?.actionNode == null)
2025-02-07 16:05:13 +08:00
{
return;
}
2025-11-18 11:27:53 +08:00
currentActionNode = nodeView.actionNode;
currentNodeView = nodeView;
2025-02-07 16:05:13 +08:00
var imguiContainer = new IMGUIContainer(() =>
{
2025-11-18 11:27:53 +08:00
if (currentActionNode == null) return;
EditorGUI.BeginChangeCheck();
DrawActionNodeInspector();
if (EditorGUI.EndChangeCheck())
2025-02-07 16:05:13 +08:00
{
2025-11-18 11:27:53 +08:00
currentNodeView?.RefreshState();
2025-02-07 16:05:13 +08:00
}
});
Add(imguiContainer);
2025-11-18 11:27:53 +08:00
}
private void DrawActionNodeInspector()
{
EditorGUILayout.BeginVertical(GUI.skin.box);
DrawQualifiedFields(currentActionNode);
EditorGUILayout.EndVertical();
}
private void DrawQualifiedFields(object targetObject)
{
if (targetObject == null) return;
Type objectType = targetObject.GetType();
// 获取所有实例字段(公共和非公共)
var allFields = objectType.GetFields(BindingFlags.Public | BindingFlags.Instance | BindingFlags.NonPublic);
foreach (var field in allFields)
{
// 跳过不应该绘制的字段
if (ShouldSkipField(field)) continue;
DrawFieldViaReflection(targetObject, field);
}
}
private bool ShouldSkipField(FieldInfo field)
{
// 跳过编译器生成的字段
if (field.IsDefined(typeof(System.Runtime.CompilerServices.CompilerGeneratedAttribute), false))
return true;
// 跳过非序列化字段但如果标记了SerializeField则仍然绘制
if (field.IsDefined(typeof(System.NonSerializedAttribute), false) && !field.IsDefined(typeof(SerializeField), false))
return true;
// 跳过静态字段
if (field.IsStatic)
return true;
// 跳过在ActionNode基类中声明的字段
if (field.DeclaringType == typeof(ActionNode))
return true;
// 跳过受保护字段protected
if (field.IsFamily)
return true;
// 关键修改只绘制公共字段或者私有但包含SerializeField特性的字段
if (!field.IsPublic && !field.IsDefined(typeof(SerializeField), false))
return true;
return false;
}
private void DrawFieldViaReflection(object targetObject, FieldInfo field)
{
try
{
var fieldValue = field.GetValue(targetObject);
var fieldType = field.FieldType;
string displayName = GetFieldDisplayName(field);
EditorGUILayout.BeginHorizontal();
var newValue = DrawFieldByType(displayName, fieldValue, fieldType);
if (!Equals(newValue, fieldValue))
{
field.SetValue(targetObject, newValue);
}
EditorGUILayout.EndHorizontal();
}
catch (Exception e)
{
EditorGUILayout.LabelField(field.Name, $"绘制错误: {e.Message}");
}
}
private string GetFieldDisplayName(FieldInfo field)
{
// 检查是否有Header特性
var headerAttr = field.GetCustomAttribute<HeaderAttribute>();
if (headerAttr != null)
{
return headerAttr.header;
}
// 将驼峰命名转换为空格分隔的友好名称
return ObjectNames.NicifyVariableName(field.Name);
}
private object DrawFieldByType(string label, object value, Type fieldType)
{
if (fieldType == typeof(string))
{
return EditorGUILayout.TextField(label, (string)value);
}
else if (fieldType == typeof(int))
{
return EditorGUILayout.IntField(label, (int)value);
}
else if (fieldType == typeof(float))
{
return EditorGUILayout.FloatField(label, (float)value);
}
else if (fieldType == typeof(bool))
{
return EditorGUILayout.Toggle(label, (bool)value);
}
else if (fieldType == typeof(Vector2))
{
return EditorGUILayout.Vector2Field(label, (Vector2)value);
}
else if (fieldType == typeof(Vector3))
{
return EditorGUILayout.Vector3Field(label, (Vector3)value);
}
else if (fieldType == typeof(Color))
{
return EditorGUILayout.ColorField(label, (Color)value);
}
else if (fieldType.IsEnum)
{
return EditorGUILayout.EnumPopup(label, (Enum)value);
}
else if (fieldType == typeof(UnityEngine.Object) || fieldType.IsSubclassOf(typeof(UnityEngine.Object)))
{
return EditorGUILayout.ObjectField(label, (UnityEngine.Object)value, fieldType, true);
}
else
{
// 对于不支持的类型,显示为只读标签
EditorGUILayout.LabelField(label, value?.ToString() ?? "null");
return value;
}
2025-02-07 16:05:13 +08:00
}
}
2025-11-18 11:27:53 +08:00
}