using System; using System.Collections.Generic; using System.Linq; using System.Reflection; using Sirenix.OdinInspector; using UnityEditor; using UnityEngine; namespace SLSUtilities.FunctionalAnimation { [CreateAssetMenu(fileName = "FuncAnimDataCollection", menuName = "Functional Animation/FuncAnimDataCollection", order = 0)] public partial class FuncAnimDataCollection : SerializedScriptableObject { [Title("武器动作集")] [Searchable] [ListDrawerSettings(ShowFoldout = true, CustomRemoveIndexFunction = "OnRemoveItem")] [OnValueChanged("OnListChanged", true)] public List animDataList = new List(); [ListDrawerSettings(ListElementLabelName = "functionName")] public List preloadFunctions = new List(); /// /// 当列表发生任何变化(添加、拖入、重新排序)时调用 /// private void OnListChanged() { if (animDataList == null) return; foreach (var data in animDataList) { if (data != null && data.parentCollection != this) { data.parentCollection = this; #if UNITY_EDITOR EditorUtility.SetDirty(data); #endif } } } /// /// 自定义删除逻辑:先解绑,再删除 /// private void OnRemoveItem(int index) { if (index < 0 || index >= animDataList.Count) return; FuncAnimData dataToRemove = animDataList[index]; if (dataToRemove != null) { // 如果它的父级确实是当前这个 Collection (防止误删别人的引用) if (dataToRemove.parentCollection == this) { dataToRemove.parentCollection = null; #if UNITY_EDITOR EditorUtility.SetDirty(dataToRemove); #endif } } animDataList.RemoveAt(index); #if UNITY_EDITOR EditorUtility.SetDirty(this); #endif } } [HideReferenceObjectPicker] public partial class CustomFunction { [LabelText("Function Name")] public string functionName; [HideInInspector] // 平时隐藏,点开下面的 Foldout 再显示 public Dictionary paramLabels = new Dictionary(); [ShowInInspector] [ShowIf("@paramCollectionType != null")] [LabelText("Parameter Labels")] [OnInspectorGUI("UpdateLabelConfig")] // 每次绘制时检查是否有新参数 private Dictionary LabelConfigDrawer { get => paramLabels; set => paramLabels = value; } [LabelText("Parameter Collection Type")] [ValueDropdown("GetFilteredTypeList")] public Type paramCollectionType; public CustomFunction() { functionName = string.Empty; paramCollectionType = typeof(PC_Void); } public string GetParamLabel(string fieldName, string defaultLabel) { if (paramLabels != null && paramLabels.TryGetValue(fieldName, out string label)) { return label; } return defaultLabel; } private void UpdateLabelConfig() { if (paramCollectionType == null) return; paramLabels ??= new Dictionary(); FieldInfo[] fields = paramCollectionType.GetFields(BindingFlags.Public | BindingFlags.Instance); foreach (var field in fields) { if (!paramLabels.ContainsKey(field.Name)) { if(field.Name == "function") continue; // 跳过 function 字段 paramLabels.Add(field.Name, field.Name); } } } } public partial class CustomFunction { public IEnumerable GetFilteredTypeList() { IEnumerable q = typeof(ParameterCollectionBase).Assembly.GetTypes() .Where(x => !x.IsAbstract) .Where(x => !x.IsGenericTypeDefinition) .Where(x => typeof(ParameterCollectionBase).IsAssignableFrom(x)); return q; } [Serializable] [HideReferenceObjectPicker] public abstract class ParameterCollectionBase { public CustomFunction function; } [Serializable] public class PC_Compound : ParameterCollectionBase { public List stringParams = new List(); public List intParams = new List(); public List floatParams = new List(); public List vector3Params = new List(); } [Serializable] public class PC_Void : ParameterCollectionBase { } [Serializable] public class PC_String : ParameterCollectionBase { [LabelText("@function.GetParamLabel(\"str0\", \"字符串参数0\")")] public string str0; } [Serializable] public class PC_StringInt : PC_String { [LabelText("@function.GetParamLabel(\"int0\", \"整数参数0\")")] public int int0; } [Serializable] public class PC_StringVector3 : PC_String { [LabelText("@function.GetParamLabel(\"vec3_0\", \"Vector3参数0\")")] public Vector3 vec3_0; } [Serializable] public class PC_StringString : PC_String { [LabelText("@function.GetParamLabel(\"str1\", \"字符串参数1\")")] public string str1; } [Serializable] public class PC_StringStringFloat : PC_StringString { [LabelText("@function.GetParamLabel(\"float0\", \"浮点数参数0\")")] public float float0; } [Serializable] public class PC_StringStringInt : PC_StringString { [LabelText("@function.GetParamLabel(\"int0\", \"整数参数0\")")] public int int0; } [Serializable] public class PC_StringStringVector3 : PC_StringString { [LabelText("@function.GetParamLabel(\"vec3_0\", \"Vector3参数0\")")] public Vector3 vec3_0; } [Serializable] public class PC_StringVector3Vector3 : PC_StringVector3 { [LabelText("@function.GetParamLabel(\"vec3_1\", \"Vector3参数1\")")] public Vector3 vec3_1; } } }