Files
ichni_Creator_Studio/Assets/Scripts/DynamicUI/Inspector/CompositeParameterWindow.cs

453 lines
19 KiB
C#
Raw Normal View History

using System.Collections;
using System.Collections.Generic;
using System.Linq;
2025-08-19 08:13:47 -04:00
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>();
2025-07-01 19:10:31 +08:00
InitializeWindow(titleText, ApplyParameters);
}
public void RemoveUnit(DynamicUICompositeUnit unit)
{
unitList.Remove(unit);
Destroy(unit.gameObject);
}
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow AddListenerFunction(UnityAction action)
2025-03-20 19:30:42 -04:00
{
onQuit = action;
2025-04-14 17:49:47 -04:00
return this;
2025-03-20 19:30:42 -04:00
}
}
public partial class CompositeParameterWindow
{
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsStringList()
{
2025-02-13 14:26:37 -05:00
//生成Unit
void GenerateUnit(string content)
{
DynamicUIInputFieldUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIInputFieldUnit>();
unitList.Add(unit);
2025-02-13 14:26:37 -05:00
unit.SetUnit(this, content);
}
unitPrefab = EditorManager.instance.basePrefabs.inputFieldUnit;
2025-02-13 14:26:37 -05:00
//初始化获取当前的List<string>并生成对应的Unit
List<string> list = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as List<string>;
foreach (string item in list)
{
2025-02-13 14:26:37 -05:00
GenerateUnit(item);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
2025-02-13 14:26:37 -05:00
//为添加新的Unit的按钮设置点击事件
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit("");
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
2025-02-13 14:26:37 -05:00
//将当前所有Unit的值应用到对应的变量中
ApplyParameters = () =>
{
List<string> stringList = unitList.Select(unit => (unit as DynamicUIInputFieldUnit).GetValue<string>()).ToList();
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, stringList);
};
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
return this;
}
2025-02-28 20:08:00 +08:00
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsFloatList()
{
void GenerateUnit(float content)
{
DynamicUIInputFieldUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIInputFieldUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-02-28 20:08:00 +08:00
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();
2025-02-28 20:08:00 +08:00
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(0);
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
2025-02-28 20:08:00 +08:00
ApplyParameters = () =>
{
List<float> floatList = unitList.Select(unit => (unit as DynamicUIInputFieldUnit).GetValue<float>()).ToList();
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, floatList);
};
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
return this;
}
public Button GotoGraphicalAnimationEditorButton;
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsFlexibleFloat()
2025-02-13 14:26:37 -05:00
{
void GenerateUnit(AnimatedFloat content)
{
DynamicUIAnimatedFloatUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIAnimatedFloatUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-02-13 14:26:37 -05:00
unitPrefab = EditorManager.instance.basePrefabs.animatedFloatUnit;
2025-02-13 14:26:37 -05:00
FlexibleFloat flexibleFloat = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as FlexibleFloat;
foreach (AnimatedFloat animatedFloat in flexibleFloat.animations)
{
GenerateUnit(animatedFloat);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
2025-02-13 14:26:37 -05:00
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new AnimatedFloat(0, 0, 0, 0, AnimationCurveType.Linear));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
2025-02-13 14:26:37 -05:00
ApplyParameters = () =>
{
FlexibleFloat newFlexibleFloat = new FlexibleFloat();
foreach (var unit in unitList)
{
newFlexibleFloat.animations.Add((unit as DynamicUIAnimatedFloatUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newFlexibleFloat);
};
2025-07-01 19:10:31 +08:00
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" });
});
2025-04-14 17:49:47 -04:00
return this;
2025-02-13 14:26:37 -05:00
}
2025-02-19 09:15:51 -05:00
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsFlexibleInt()
2025-02-19 09:15:51 -05:00
{
void GenerateUnit(AnimatedInt content)
{
DynamicUIAnimatedIntUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIAnimatedIntUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-02-19 09:15:51 -05:00
unitPrefab = EditorManager.instance.basePrefabs.animatedIntUnit;
2025-02-19 09:15:51 -05:00
FlexibleInt flexibleInt = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as FlexibleInt;
foreach (AnimatedInt animatedInt in flexibleInt.animations)
{
GenerateUnit(animatedInt);
}
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
2025-02-19 09:15:51 -05:00
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new AnimatedInt(0, 0));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
2025-02-19 09:15:51 -05:00
ApplyParameters = () =>
{
FlexibleInt newFlexibleInt = new FlexibleInt();
foreach (var unit in unitList)
{
newFlexibleInt.animations.Add((unit as DynamicUIAnimatedIntUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newFlexibleInt);
};
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
return this;
2025-02-19 09:15:51 -05:00
}
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsFlexibleBool()
2025-02-19 09:15:51 -05:00
{
void GenerateUnit(AnimatedBool content)
{
DynamicUIAnimatedBoolUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIAnimatedBoolUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-02-19 09:15:51 -05:00
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();
2025-02-19 09:15:51 -05:00
addNewUnitButton.onClick.AddListener(() =>
{
GenerateUnit(new AnimatedBool(0, false));
addNewUnitButton.GetComponent<RectTransform>().SetAsLastSibling();
});
2025-02-19 09:15:51 -05:00
ApplyParameters = () =>
{
FlexibleBool newFlexibleBool = new FlexibleBool();
foreach (var unit in unitList)
{
newFlexibleBool.animations.Add((unit as DynamicUIAnimatedBoolUnit).GetValue());
}
connectedBaseElement.GetType().GetField(parameterName).SetValue(connectedBaseElement, newFlexibleBool);
};
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
return this;
2025-02-19 09:15:51 -05:00
}
2025-07-01 19:10:31 +08:00
public KeyframeVisualizer keyframeVisualizer;
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsCustomCurve()
{
2025-07-01 19:10:31 +08:00
keyframeVisualizer.gameObject.SetActive(true);
2025-02-28 20:08:00 +08:00
// 获取字段信息和曲线数据
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);
2025-02-28 20:08:00 +08:00
// 初始化预览器
2025-07-01 19:10:31 +08:00
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);
2025-02-28 20:08:00 +08:00
// 生成 Keyframe 单元
void GenerateUnit(Keyframe content)
{
var unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUICustomCurveKeyframeUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-02-28 20:08:00 +08:00
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();
});
2025-02-28 20:08:00 +08:00
// 真正的应用/保存逻辑
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
2025-02-28 20:08:00 +08:00
for (int i = 1; i < unitList.Count; i++)
{
var kUnit = unitList[i] as DynamicUICustomCurveKeyframeUnit;
newCurve.AddKey(kUnit.GetValue());
}
2025-08-19 08:13:47 -04:00
fieldInfo.SetValue(connectedBaseElement, newCurve);
keyframeVisualizer.curve = newCurve;
keyframeVisualizer.DrawCurveToRawImage();
};
2025-04-14 17:49:47 -04:00
return this;
}
2025-04-19 13:51:47 -04:00
public CompositeParameterWindow SetAsGradientColorKeys()
{
void GenerateUnit(GradientColorKey content)
{
DynamicUIGradientColorKeyUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIGradientColorKeyUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
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();
});
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
ApplyParameters = () =>
{
List<GradientColorKey> newColorKeys = new List<GradientColorKey>();
foreach (var unit in unitList)
{
newColorKeys.Add((unit as DynamicUIGradientColorKeyUnit).GetValue());
}
2025-08-19 08:13:47 -04:00
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);
2025-04-19 13:51:47 -04:00
};
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
return this;
}
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
public CompositeParameterWindow SetAsGradientAlphaKeys()
{
void GenerateUnit(GradientAlphaKey content)
{
DynamicUIGradientAlphaKeyUnit unit = Instantiate(unitPrefab, windowRect).GetComponent<DynamicUIGradientAlphaKeyUnit>();
unitList.Add(unit);
unit.SetUnit(this, content);
}
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
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();
});
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
ApplyParameters = () =>
{
List<GradientAlphaKey> newAlphaKeys = new List<GradientAlphaKey>();
foreach (var unit in unitList)
{
newAlphaKeys.Add((unit as DynamicUIGradientAlphaKeyUnit).GetValue());
}
2025-08-19 08:13:47 -04:00
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);
2025-04-19 13:51:47 -04:00
};
2025-07-01 19:10:31 +08:00
2025-04-19 13:51:47 -04:00
return this;
}
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
public CompositeParameterWindow SetAsStringIntDictionary()
{
2025-03-20 19:30:42 -04:00
//生成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;
2025-07-01 19:10:31 +08:00
2025-03-20 19:30:42 -04:00
Dictionary<string, int> dictionary = connectedBaseElement.GetType().GetField(parameterName).GetValue(connectedBaseElement) as Dictionary<string, int>;
foreach (var pair in dictionary)
{
GenerateUnit(pair);
}
2025-07-01 19:10:31 +08:00
2025-03-20 19:30:42 -04:00
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);
}
2025-08-19 08:13:47 -04:00
FieldInfo fieldInfo = connectedBaseElement.GetType().GetField(parameterName);
fieldInfo.SetValue(connectedBaseElement, dictionaryList);
2025-03-20 19:30:42 -04:00
};
2025-07-01 19:10:31 +08:00
2025-04-14 17:49:47 -04:00
return this;
}
}
}