210 lines
6.8 KiB
C#
210 lines
6.8 KiB
C#
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<FuncAnimData> animDataList = new List<FuncAnimData>();
|
|
|
|
[ListDrawerSettings(ListElementLabelName = "functionName")]
|
|
public List<CustomFunction> preloadFunctions = new List<CustomFunction>();
|
|
|
|
/// <summary>
|
|
/// 当列表发生任何变化(添加、拖入、重新排序)时调用
|
|
/// </summary>
|
|
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
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// 自定义删除逻辑:先解绑,再删除
|
|
/// </summary>
|
|
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<string, string> paramLabels = new Dictionary<string, string>();
|
|
|
|
[ShowInInspector]
|
|
[ShowIf("@paramCollectionType != null")]
|
|
[LabelText("Parameter Labels")]
|
|
[OnInspectorGUI("UpdateLabelConfig")] // 每次绘制时检查是否有新参数
|
|
private Dictionary<string, string> 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<string, string>();
|
|
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<Type> GetFilteredTypeList()
|
|
{
|
|
IEnumerable<Type> 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<string> stringParams = new List<string>();
|
|
public List<int> intParams = new List<int>();
|
|
public List<float> floatParams = new List<float>();
|
|
public List<Vector3> vector3Params = new List<Vector3>();
|
|
}
|
|
|
|
[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;
|
|
}
|
|
}
|
|
} |