Files
Cielonos/Assets/Scripts/SLSUtilities/FunctionalAnimation/FuncAnimDataCollection.cs
SoulliesOfficial f26f9fd374 爆更
2026-03-20 12:07:44 -04:00

209 lines
6.7 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("武器动作集")]
[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;
}
}
}