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

184 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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;
}
}
}
}