Files
ichni_Creator_Studio/Assets/Scripts/DynamicUI/Inspector/CompositeParameterWindow.cs
2026-02-09 23:10:55 +08:00

453 lines
19 KiB
C#
Raw Permalink 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.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
namespace Ichni.Editor
{
public partial class CompositeParameterWindow : MovableWindow
{
public Button addNewUnitButton;
public GameObject unitPrefab;
public IBaseElement connectedBaseElement;
public List<DynamicUICompositeUnit> unitList;
public string parameterName;
public UnityAction ApplyParameters;
public void Initialize(IBaseElement baseElement, string titleText, string parameterName)
{
transform.localScale = Vector3.zero;
this.connectedBaseElement = baseElement;
this.parameterName = parameterName;
unitList = new List<DynamicUICompositeUnit>();
InitializeWindow(titleText, ApplyParameters);
}
public void RemoveUnit(DynamicUICompositeUnit unit)
{
unitList.Remove(unit);
Destroy(unit.gameObject);
}
public CompositeParameterWindow AddListenerFunction(UnityAction action)
{
onQuit = action;
return this;
}
}
public partial class CompositeParameterWindow
{
public CompositeParameterWindow SetAsStringList()
{
//生成Unit
void GenerateUnit(string content)
{
DynamicUIInputFieldUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIInputFieldUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.inputFieldUnit;
//初始化获取当前的List<string>并生成对应的Unit
List<string> list = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as List<string>;
foreach (string item in list)
{
GenerateUnit(item);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
//为添加新的Unit的按钮设置点击事件
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit("");
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
//将当前所有Unit的值应用到对应的变量中
ApplyParameters = () =>
{
List<string> stringList = unitList.Select(unit => (unit as DynamicUIInputFieldUnit).GetValue<string>()).ToList();
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, stringList);
};
return this;
}
public CompositeParameterWindow SetAsFloatList()
{
void GenerateUnit(float content)
{
DynamicUIInputFieldUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIInputFieldUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.inputFieldUnit;
List<float> list = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as List<float>;
foreach (float item in list)
{
GenerateUnit(item);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(0);
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
ApplyParameters = () =>
{
List<float> floatList = unitList.Select(unit => (unit as DynamicUIInputFieldUnit).GetValue<float>()).ToList();
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, floatList);
};
return this;
}
public Button GotoGraphicalAnimationEditorButton;
public CompositeParameterWindow SetAsFlexibleFloat()
{
void GenerateUnit(AnimatedFloat content)
{
DynamicUIAnimatedFloatUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIAnimatedFloatUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.animatedFloatUnit;
FlexibleFloat flexibleFloat = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as FlexibleFloat;
foreach (AnimatedFloat animatedFloat in flexibleFloat.animations)
{
GenerateUnit(animatedFloat);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new AnimatedFloat(0, 0, 0, 0, AnimationCurveType.Linear));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
ApplyParameters = () =>
{
FlexibleFloat newFlexibleFloat = new FlexibleFloat();
foreach (var unit in unitList)
{
newFlexibleFloat.animations.Add((unit as DynamicUIAnimatedFloatUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newFlexibleFloat);
};
GotoGraphicalAnimationEditorButton.gameObject.SetActive(true); // 隐藏按钮
GotoGraphicalAnimationEditorButton.onClick.AddListener(() =>
{
// 打开Graphical Animation Editor
IHaveInspection i = EditorManager.instance.uiManager.inspector as IHaveInspection;
i.GenerateGraphicalFlexibleFloatWindow(connectedBaseElement, "Graphical Animation Editor", new FlexibleFloat[] { flexibleFloat }, new string[] { "1" });
});
return this;
}
public CompositeParameterWindow SetAsFlexibleInt()
{
void GenerateUnit(AnimatedInt content)
{
DynamicUIAnimatedIntUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIAnimatedIntUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.animatedIntUnit;
FlexibleInt flexibleInt = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as FlexibleInt;
foreach (AnimatedInt animatedInt in flexibleInt.animations)
{
GenerateUnit(animatedInt);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new AnimatedInt(0, 0));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
ApplyParameters = () =>
{
FlexibleInt newFlexibleInt = new FlexibleInt();
foreach (var unit in unitList)
{
newFlexibleInt.animations.Add((unit as DynamicUIAnimatedIntUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newFlexibleInt);
};
return this;
}
public CompositeParameterWindow SetAsFlexibleBool()
{
void GenerateUnit(AnimatedBool content)
{
DynamicUIAnimatedBoolUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIAnimatedBoolUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.animatedBoolUnit;
FlexibleBool flexibleBool = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as FlexibleBool;
foreach (AnimatedBool animatedBool in flexibleBool.animations)
{
GenerateUnit(animatedBool);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new AnimatedBool(0, false));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
ApplyParameters = () =>
{
FlexibleBool newFlexibleBool = new FlexibleBool();
foreach (var unit in unitList)
{
newFlexibleBool.animations.Add((unit as DynamicUIAnimatedBoolUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newFlexibleBool);
};
return this;
}
public KeyframeVisualizer keyframeVisualizer;
public CompositeParameterWindow SetAsCustomCurve()
{
keyframeVisualizer.gameObject.SetActive(true);
// 获取字段信息和曲线数据
unitPrefab = EditorManager.instance.basePrefabs.customCurveKeyframeUnit;
FieldInfo fieldInfo = connectedBaseElement.GetType().GetField(parameterName);
AnimationCurve curve = fieldInfo.GetValue(connectedBaseElement) as AnimationCurve;
if (curve == null) curve = AnimationCurve.Linear(0, 0, 1, 1);
// 初始化预览器
keyframeVisualizer.curve = curve;
keyframeVisualizer.DrawCurveToRawImage();
keyframeVisualizer.RebuildInteractablePoints();
// 关键点:松开手柄时的回调
keyframeVisualizer.OnEditFinished = () =>
{
// 同步左侧 Unit 列表的数值显示(假设 unitList[0] 是 WrapMode
for (int i = 0; i < keyframeVisualizer.curve.length; i++)
{
int unitIdx = i + 1;
if (unitIdx < unitList.Count)
{
var unit = unitList[unitIdx] as DynamicUICustomCurveKeyframeUnit;
if (unit != null) unit.SetUnit(this, keyframeVisualizer.curve.keys[i]);
}
}
ApplyParameters?.Invoke();
};
// 生成 WrapMode 单元
WarpModes warpModes = new WarpModes(curve.preWrapMode, curve.postWrapMode);
var wmUnit = Instantiate(EditorManager.instance.basePrefabs.customCurveWrapModeUnit, windowRect)
.GetComponent<DynamicUICustomCurveWrapModeUnit>();
unitList.Add(wmUnit);
wmUnit.SetUnit(this, warpModes);
// 生成 Keyframe 单元
void GenerateUnit(Keyframe content)
{
var unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUICustomCurveKeyframeUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
foreach (Keyframe k in curve.keys) GenerateUnit(k);
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
Keyframe newKey = new Keyframe(0.5f, 0.5f, 0, 0);
keyframeVisualizer.curve.AddKey(newKey);
GenerateUnit(newKey);
keyframeVisualizer.RebuildInteractablePoints();
keyframeVisualizer.DrawCurveToRawImage();
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
// 真正的应用/保存逻辑
ApplyParameters = () =>
{
AnimationCurve newCurve = new AnimationCurve();
// 1. 获取 WrapMode
var wUnit = unitList[0] as DynamicUICustomCurveWrapModeUnit;
newCurve.preWrapMode = wUnit.GetValue().preWrapMode;
newCurve.postWrapMode = wUnit.GetValue().postWrapMode;
// 2. 获取所有 Keyframes
for (int i = 1; i < unitList.Count; i++)
{
var kUnit = unitList[i] as DynamicUICustomCurveKeyframeUnit;
newCurve.AddKey(kUnit.GetValue());
}
fieldInfo.SetValue(connectedBaseElement, newCurve);
keyframeVisualizer.curve = newCurve;
keyframeVisualizer.DrawCurveToRawImage();
};
return this;
}
public CompositeParameterWindow SetAsGradientColorKeys()
{
void GenerateUnit(GradientColorKey content)
{
DynamicUIGradientColorKeyUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIGradientColorKeyUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.gradientColorKeyUnit;
Gradient gradient = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as Gradient;
List<GradientColorKey> colorKeys = gradient.colorKeys.ToList();
foreach (GradientColorKey colorKey in colorKeys)
{
GenerateUnit(colorKey);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new GradientColorKey(Color.white, 1));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
ApplyParameters = () =>
{
List<GradientColorKey> newColorKeys = new List<GradientColorKey>();
foreach (var unit in unitList)
{
newColorKeys.Add((unit as DynamicUIGradientColorKeyUnit).GetValue());
}
FieldInfo fieldInfo = connectedBaseElement.GetType().GetField(parameterName);
Gradient originalGradient = fieldInfo.GetValue(connectedBaseElement) as Gradient;
Gradient newIndependentGradient = new Gradient();
newIndependentGradient.alphaKeys = originalGradient.alphaKeys;
newIndependentGradient.mode = originalGradient.mode;
newIndependentGradient.colorKeys = newColorKeys.ToArray();
fieldInfo.SetValue(connectedBaseElement, newIndependentGradient);
};
return this;
}
public CompositeParameterWindow SetAsGradientAlphaKeys()
{
void GenerateUnit(GradientAlphaKey content)
{
DynamicUIGradientAlphaKeyUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIGradientAlphaKeyUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.gradientAlphaKeyUnit;
Gradient gradient = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as Gradient;
List<GradientAlphaKey> alphaKeys = gradient.alphaKeys.ToList();
foreach (GradientAlphaKey alphaKey in alphaKeys)
{
GenerateUnit(alphaKey);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new GradientAlphaKey(1, 1));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
ApplyParameters = () =>
{
List<GradientAlphaKey> newAlphaKeys = new List<GradientAlphaKey>();
foreach (var unit in unitList)
{
newAlphaKeys.Add((unit as DynamicUIGradientAlphaKeyUnit).GetValue());
}
FieldInfo fieldInfo = connectedBaseElement.GetType().GetField(parameterName);
Gradient originalGradient = fieldInfo.GetValue(connectedBaseElement) as Gradient;
Gradient newIndependentGradient = new Gradient();
newIndependentGradient.colorKeys = originalGradient.colorKeys;
newIndependentGradient.mode = originalGradient.mode;
newIndependentGradient.alphaKeys = newAlphaKeys.ToArray();
fieldInfo.SetValue(connectedBaseElement, newIndependentGradient);
};
return this;
}
public CompositeParameterWindow SetAsStringIntDictionary()
{
//生成Unit
void GenerateUnit(KeyValuePair<string, int> content)
{
DynamicUIStringIntPairUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIStringIntPairUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.stringIntPairUnit;
Dictionary<string, int> dictionary = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as Dictionary<string, int>;
foreach (var pair in dictionary)
{
GenerateUnit(pair);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
//为添加新的Unit的按钮设置点击事件
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new KeyValuePair<string, int>("New Variable", 0));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
//将当前所有Unit的值应用到对应的变量中
ApplyParameters = () =>
{
Dictionary<string, int> dictionaryList = new Dictionary<string, int>();
foreach (var unit in unitList)
{
KeyValuePair<string, int> pair = (unit as DynamicUIStringIntPairUnit).GetValue();
dictionaryList.Add(pair.Key, pair.Value);
}
FieldInfo fieldInfo = connectedBaseElement.GetType().GetField(parameterName);
fieldInfo.SetValue(connectedBaseElement, dictionaryList);
};
return this;
}
}
}