184 lines
5.8 KiB
C#
184 lines
5.8 KiB
C#
using System;
|
||
using System.Reflection;
|
||
using AlicizaX.AnimationFlow.Runtime;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
using UnityEngine.UIElements;
|
||
|
||
namespace AlicizaX.AnimationFlow.Editor
|
||
{
|
||
public class GraphInspector : VisualElement
|
||
{
|
||
private ActionNode currentActionNode;
|
||
private NodeView currentNodeView;
|
||
|
||
public void DrawNode(NodeView nodeView)
|
||
{
|
||
Clear();
|
||
if (nodeView?.actionNode == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
currentActionNode = nodeView.actionNode;
|
||
currentNodeView = nodeView;
|
||
|
||
var imguiContainer = new IMGUIContainer(() =>
|
||
{
|
||
if (currentActionNode == null) return;
|
||
|
||
EditorGUI.BeginChangeCheck();
|
||
|
||
DrawActionNodeInspector();
|
||
|
||
if (EditorGUI.EndChangeCheck())
|
||
{
|
||
currentNodeView?.RefreshState();
|
||
}
|
||
});
|
||
|
||
Add(imguiContainer);
|
||
}
|
||
|
||
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;
|
||
}
|
||
}
|
||
}
|
||
}
|