132 lines
5.3 KiB
C#
132 lines
5.3 KiB
C#
using System;
|
||
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using Sirenix.OdinInspector;
|
||
using SLSUtilities.FunctionalAnimation;
|
||
using UnityEditor;
|
||
using UnityEngine;
|
||
|
||
namespace Cielonos.MainGame.FunctionalAnimation
|
||
{
|
||
public partial class InvokePreloadFunction : FuncAnimPayloadBase
|
||
{
|
||
private bool HasCollection => parentData != null && parentData.parentCollection != null;
|
||
|
||
public override string NameForInspector => $"Preload Function: {functionKey}";
|
||
|
||
[InfoBox("此 Data 未连接到 FuncAnimDataCollection,无法获取函数列表。\n请在 FuncAnimData 的顶部进行连接。", InfoMessageType.Error, "@!this.HasCollection")]
|
||
[PropertyOrder(-1)]
|
||
[EnableIf("HasCollection")] // 只有连接了才能选
|
||
[OnInspectorInit("RefreshParameterReference")] // 初始化时刷新参数引用
|
||
[ValueDropdown("GetFunctionKeys")]
|
||
[OnValueChanged("OnFunctionKeyChanged")]
|
||
[InlineButton("RefreshParameterInputFields", "R")]
|
||
public string functionKey;
|
||
|
||
[HideLabel] // 隐藏字段名,让参数看起来像直接嵌入的
|
||
[SerializeReference]
|
||
[HideReferenceObjectPicker] // 隐藏类型选择器,强制由 Key 决定
|
||
[InfoBox("请先选择一个函数。", InfoMessageType.Warning, "@this.parameters == null && !string.IsNullOrEmpty(this.functionKey)")]
|
||
public CustomFunction.ParameterCollectionBase parameters;
|
||
|
||
public override void Invoke()
|
||
{
|
||
if (runtimeFuncAnim == null || mute) return;
|
||
|
||
runtimeFuncAnim.currentActionParams = this.parameters;
|
||
|
||
if (!string.IsNullOrEmpty(functionKey) &&
|
||
character.animationSc.registeredFunctions.TryGetValue(functionKey, out var func))
|
||
{
|
||
func.Invoke(runtimeFuncAnim);
|
||
}
|
||
else
|
||
{
|
||
Debug.LogWarning($"[InvokePreRegisteredFunction] 试图调用 '{functionKey}',但该函数未在 AnimationSc 中注册。");
|
||
}
|
||
}
|
||
}
|
||
|
||
public partial class InvokePreloadFunction
|
||
{
|
||
private void RefreshParameterReference()
|
||
{
|
||
if (parentData == null || parameters == null || string.IsNullOrEmpty(functionKey)) return;
|
||
|
||
if (!HasCollection) return;
|
||
|
||
List<CustomFunction> functions = parentData.parentCollection.preloadFunctions;
|
||
CustomFunction selectedFunc = functions.Find(func => func.functionName == functionKey);
|
||
if (selectedFunc != null)
|
||
{
|
||
parameters.function = selectedFunc;
|
||
}
|
||
}
|
||
|
||
private IEnumerable GetFunctionKeys()
|
||
{
|
||
if (!HasCollection) return null;
|
||
|
||
List<CustomFunction> functions = parentData.parentCollection.preloadFunctions;
|
||
if (functions == null || functions.Count == 0) return null;
|
||
|
||
return functions.ConvertAll(func => func.functionName);
|
||
}
|
||
|
||
private void OnFunctionKeyChanged()
|
||
{
|
||
if (!HasCollection) return;
|
||
|
||
CustomFunction selectedFunc = parentData.parentCollection.preloadFunctions.Find(func => func.functionName == functionKey);
|
||
if (selectedFunc != null)
|
||
{
|
||
parameters = Activator.CreateInstance(selectedFunc.paramCollectionType) as CustomFunction.ParameterCollectionBase;
|
||
if (parameters != null)
|
||
{
|
||
parameters.function = selectedFunc;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
parameters = null;
|
||
}
|
||
}
|
||
|
||
//如果collection中的参数类型发生了变化,或者之前的参数实例被重置了,这个方法可以用来刷新参数输入字段
|
||
private void RefreshParameterInputFields()
|
||
{
|
||
if (!HasCollection) return;
|
||
|
||
CustomFunction selectedFunc = parentData.parentCollection.preloadFunctions.Find(func => func.functionName == functionKey);
|
||
if (selectedFunc != null)
|
||
{
|
||
Type currentParamType = parameters.GetType();
|
||
Type newParamType = selectedFunc.paramCollectionType;
|
||
var newParameters = Activator.CreateInstance(newParamType) as CustomFunction.ParameterCollectionBase;
|
||
//如果collection中的参数类型和当前的有继承关系,尽可能保留相同的参数
|
||
if (currentParamType.IsSubclassOf(newParamType) || newParamType.IsSubclassOf(currentParamType))
|
||
{
|
||
foreach (var field in currentParamType.GetFields())
|
||
{
|
||
var newField = newParamType.GetField(field.Name);
|
||
if (newField != null && newField.FieldType == field.FieldType)
|
||
{
|
||
newField.SetValue(newParameters, field.GetValue(parameters));
|
||
}
|
||
}
|
||
}
|
||
|
||
parameters = newParameters;
|
||
|
||
if (parameters != null)
|
||
{
|
||
parameters.function = selectedFunc;
|
||
}
|
||
}
|
||
else
|
||
{
|
||
parameters = null;
|
||
}
|
||
}
|
||
}
|
||
} |