事件编辑器初步

待办:
添加删除
复制粘贴
曲线预览
This commit is contained in:
2025-03-01 01:20:40 +08:00
parent e638d1cec2
commit 210e594808
22 changed files with 5904 additions and 48 deletions

View File

@@ -15,11 +15,16 @@ namespace Ichni.Editor
public TMP_InputField startValueInputField;
public TMP_InputField endValueInputField;
public TMP_Dropdown animationCurveTypeDropdown;
public override void SetUnit(CompositeParameterWindow window, object itemContent)
{
startTimeInputField.text = "0";
endTimeInputField.text = "0";
startValueInputField.text = "0";
endValueInputField.text = "0";
animationCurveTypeDropdown.value = 0;
compositeParameterWindow = window;
AnimatedFloat animatedFloat = (AnimatedFloat)itemContent;
startTimeInputField.text = animatedFloat.startTime.ToString();
endTimeInputField.text = animatedFloat.endTime.ToString();
@@ -29,14 +34,14 @@ namespace Ichni.Editor
List<string> enumNameList = System.Enum.GetNames(typeof(AnimationCurveType)).ToList();
animationCurveTypeDropdown.AddOptions(enumNameList);
animationCurveTypeDropdown.value = (int)animatedFloat.animationCurveType;
startTimeInputField.onEndEdit.AddListener(_ => compositeParameterWindow.ApplyParameters());
endTimeInputField.onEndEdit.AddListener(_ => compositeParameterWindow.ApplyParameters());
startValueInputField.onEndEdit.AddListener(_ => compositeParameterWindow.ApplyParameters());
endValueInputField.onEndEdit.AddListener(_ => compositeParameterWindow.ApplyParameters());
animationCurveTypeDropdown.onValueChanged.AddListener(_ => compositeParameterWindow.ApplyParameters());
removeButton.onClick.AddListener(() =>
{
compositeParameterWindow.RemoveUnit(this);

View File

@@ -23,7 +23,13 @@ namespace Ichni.Editor
compositeParameterWindow.Initialize(baseElement, title, parameterName);
return compositeParameterWindow;
}
public GraphicalFlexibleFloatWindow GenerateGraphicalFlexibleFloatWindow(IBaseElement baseElement, string title, FlexibleFloat[] FlexibleFloats, string[] subTitle)
{
GraphicalFlexibleFloatWindow graphicalFlexibleFloatWindow = Object.Instantiate(EditorManager.instance.basePrefabs.graphicalFlexibleFloatWindow, EditorManager.instance.uiManager.inspector.inspectorCanvas.GetComponent<RectTransform>())
.GetComponent<GraphicalFlexibleFloatWindow>();
graphicalFlexibleFloatWindow.Initialize(baseElement, title, FlexibleFloats, subTitle);
return graphicalFlexibleFloatWindow;
}
public DynamicUIContainer GenerateContainer(string title)
{
DynamicUIContainer container =
@@ -88,8 +94,8 @@ namespace Ichni.Editor
container.dynamicUIElements.Add(inputField);
return inputField;
}
public DynamicUIVector3InputField GenerateVector3InputField(DynamicUIContainer container, string title,
public DynamicUIVector3InputField GenerateVector3InputField(DynamicUIContainer container, string title,
Vector3 defaultVector3 = default)
{
DynamicUIVector3InputField vector3InputField =

View File

@@ -17,21 +17,21 @@ namespace Ichni.RhythmGame
private TransformSubmodule targetTransformSubmodule;
public FlexibleFloat positionX, positionY, positionZ;
public static Displacement GenerateElement(string elementName, Guid id,
public static Displacement GenerateElement(string elementName, Guid id,
List<string> tags, bool isFirstGenerated, GameElement animatedObject,
FlexibleFloat positionX, FlexibleFloat positionY, FlexibleFloat positionZ)
{
Displacement displacement = Instantiate(EditorManager.instance.basePrefabs.emptyObject).AddComponent<Displacement>();
displacement.Initialize(elementName, id, tags, isFirstGenerated, animatedObject);
displacement.animatedObject = animatedObject;
displacement.positionX = positionX;
displacement.positionY = positionY;
displacement.positionZ = positionZ;
displacement.animationReturnType = FlexibleReturnType.Before;
displacement.targetTransformSubmodule = (animatedObject as IHaveTransformSubmodule).transformSubmodule;
//displacement.timeDurationSubmodule.SetDuration(positionX, positionY, positionZ);
@@ -44,9 +44,9 @@ namespace Ichni.RhythmGame
positionX.UpdateFlexibleFloat(songTime);
positionY.UpdateFlexibleFloat(songTime);
positionZ.UpdateFlexibleFloat(songTime);
if (positionX.returnType is FlexibleReturnType.MiddleExecuting or FlexibleReturnType.After or FlexibleReturnType.Before ||
positionY.returnType is FlexibleReturnType.MiddleExecuting or FlexibleReturnType.After or FlexibleReturnType.Before ||
if (positionX.returnType is FlexibleReturnType.MiddleExecuting or FlexibleReturnType.After or FlexibleReturnType.Before ||
positionY.returnType is FlexibleReturnType.MiddleExecuting or FlexibleReturnType.After or FlexibleReturnType.Before ||
positionZ.returnType is FlexibleReturnType.MiddleExecuting or FlexibleReturnType.After or FlexibleReturnType.Before)
{
animationReturnType = FlexibleReturnType.MiddleExecuting;
@@ -68,12 +68,12 @@ namespace Ichni.RhythmGame
positionZ.animations.ForEach(anim => anim.ApplyTimeOffset(offset));
}
}
public partial class Displacement
{
public override void SaveBM()
{
matchedBM = new Beatmap.Displacement_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
matchedBM = new Beatmap.Displacement_BM(elementName, elementGuid, tags, parentElement.matchedBM as GameElement_BM,
positionX.ConvertToBM(), positionY.ConvertToBM(), positionZ.ConvertToBM());
}
@@ -97,21 +97,27 @@ namespace Ichni.RhythmGame
{
inspector.GenerateCompositeParameterWindow(this, "Position Z", nameof(positionZ)).SetAsFlexibleFloat();
});
var GraphicEditor = inspector.GenerateButton(this, container, "GraphicEditor",
() =>
{
inspector.GenerateGraphicalFlexibleFloatWindow(this, "Displacement",
new FlexibleFloat[] { positionX, positionY, positionZ }, new string[] { "PosX", "PosY", "PosZ" });
});
container.SetDeviver(1);
}
}
namespace Beatmap
{
public class Displacement_BM : AnimationBase_BM
{
public FlexibleFloat_BM positionX, positionY, positionZ;
public Displacement_BM()
{
}
public Displacement_BM(string elementName, Guid elementGuid, List<string> tags,
GameElement_BM attachedElement, FlexibleFloat_BM positionX, FlexibleFloat_BM positionY, FlexibleFloat_BM positionZ)
: base(elementName, elementGuid, tags, attachedElement)
@@ -120,10 +126,10 @@ namespace Ichni.RhythmGame
this.positionY = positionY;
this.positionZ = positionZ;
}
public override void ExecuteBM()
{
matchedElement = Displacement.GenerateElement(elementName, elementGuid, tags, false, GetElement(attachedElementGuid),
matchedElement = Displacement.GenerateElement(elementName, elementGuid, tags, false, GetElement(attachedElementGuid),
positionX.ConvertToGameType(), positionY.ConvertToGameType(), positionZ.ConvertToGameType());
}

View File

@@ -0,0 +1,47 @@
using System.Collections;
using System.Collections.Generic;
using Ichni;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.UI;
public class EventPoint : MonoBehaviour
{
public AnimatedFloat animatedFloat;
public EventPoint LastEventPoint;
public EventPoint NextEventPoint;
public Image EvDrawimage;
public Image OvDrawimage;
public RectTransform LeftSide;
public RectTransform RightSide;
public Button selectButton;
public FlexibleFloatTab FatherTab;
public int BeatDeviver => FatherTab.BeatDeviver;
public void Initialize(AnimatedFloat animatedFloat)
{
this.animatedFloat = animatedFloat;
transform.localPosition = new Vector3(
animatedFloat.startTime / EditorManager.instance.timeline.timePerBeat * BeatDeviver, 0, 0
);
RightSide.localPosition = new Vector3(
(animatedFloat.endTime - animatedFloat.startTime) / EditorManager.instance.timeline.timePerBeat * BeatDeviver, 0, 0);
EvDrawimage.rectTransform.sizeDelta = new Vector2(RightSide.localPosition.x - transform.localPosition.x, EvDrawimage.rectTransform.sizeDelta.y);
EvDrawimage.transform.localPosition = new Vector3(EvDrawimage.rectTransform.sizeDelta.x / 2, 0, 0);
OvDrawimage.transform.localPosition = RightSide.localPosition;
ReDraw();
}
private void ReDraw()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b4c5757a536b2e14bbb3c3fa2ed0a8e4
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,56 @@
using System.Collections;
using System.Collections.Generic;
using System.Data;
using Ichni;
using Ichni.RhythmGame;
using UnityEngine;
public class FlexibleFloatTab : MonoBehaviour
{
public FlexibleFloat flexibleFloat;
public GraphicalFlexibleFloatWindow FatherWindow;
public List<EventPoint> eventPoints;
public RectTransform Area;
public RectTransform BeatArea;
public EventPoint eventPoint;
public GameObject BeatLine;
public int BeatDeviver => FatherWindow.BeatDeviver;
public void Initialize(FlexibleFloat flexibleFloat, string Title)
{
for (int i = 0; i < (int)EditorManager.instance.songInformation.song.length / FatherWindow.timePerBeat; i++)
{
GameObject u = Instantiate(BeatLine, BeatArea);
u.transform.localPosition = new Vector3(BeatDeviver * i, 0, 0);
}
for (int i = 0; i <= flexibleFloat.animations.Count - 1; i++)
{
AnimatedFloat animatedFloat = flexibleFloat.animations[i];
EventPoint eventPoint = Instantiate(this.eventPoint, Area);
eventPoint.FatherTab = this;
eventPoint.Initialize(animatedFloat);
eventPoints.Add(eventPoint);
if (i - 1 >= 0)
{
eventPoint.LastEventPoint = eventPoints[i - 1];
eventPoint.LastEventPoint.NextEventPoint = eventPoint;
}
else eventPoint.LastEventPoint = null;
if (i == flexibleFloat.animations.Count - 1) eventPoint.NextEventPoint = null;
}
Area.localPosition = new Vector3(FatherWindow.songBeat * BeatDeviver, 0, 0);
}
public void Update()
{
Area.localPosition = new Vector3(-FatherWindow.songBeat * BeatDeviver, 0, 0);
BeatArea.localPosition = Area.localPosition;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 20904e6182baed446b49fe294fad22b2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,71 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Ichni;
using Ichni.Editor;
using Ichni.RhythmGame;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
public class GraphicalFlexibleFloatWindow : MovableWindow
{
public Button addNewUnitButton;
public FlexibleFloatTab unitPrefab;
public IBaseElement connectedBaseElement;
public List<FlexibleFloatTab> unitList;
public string parameterName;
public UnityAction ApplyParameters;
public float songTime => EditorManager.instance.songInformation.songTime;
public float songBeat => EditorManager.instance.songInformation.songBeat;
public float beatmapStartTime => -EditorManager.instance.songInformation.delay;
public float timePerBeat => 60f / EditorManager.instance.songInformation.bpm;
public int BeatDeviver = 100;
public void Initialize(IBaseElement baseElement, string title, FlexibleFloat[] FlexibleFloats, string[] Subtitles)
{
transform.localScale = Vector3.zero;
this.connectedBaseElement = baseElement;
this.title.text = title;
unitList = new List<FlexibleFloatTab>();
for (int i = 0; i <= FlexibleFloats.Length - 1; i++)
{
AddUnit(FlexibleFloats[i], Subtitles[i]);
}
closeButton.onClick.AddListener(Quit);
StartCoroutine(WindowAnim.ShowPanelOnScale(gameObject));
ApplyParameters = () =>
{
for (int i = 0; i <= unitList.Count - 1; i++)
{
unitList[i].flexibleFloat.Sort();
}
//Dangered
//connectedBaseElement.SetParameter(parameterName, unitList.Select(unit => unit.flexibleFloat).ToArray());
};
}
public void AddUnit(FlexibleFloat flexibleFloat, string Subtitle)
{
flexibleFloat.Sort();
FlexibleFloatTab flexibleFloatTab = Instantiate(unitPrefab, windowRect);
flexibleFloatTab.FatherWindow = this;
unitList.Add(flexibleFloatTab);
flexibleFloatTab.Initialize(flexibleFloat, Subtitle);
}
public void Quit()
{
ApplyParameters();
//StartCoroutine(WindowAnim.HidePanel(gameObject, true));
Destroy(gameObject);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f9ccff815b775ec48abb8e62577257f8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -36,8 +36,8 @@ public class BasePrefabsCollection : SerializedScriptableObject
public GameObject vignetteEffect;
[Title("Inspector相关")]
public GameObject inspectorSecondaryWindow;
public GameObject inspectorSecondaryWindow;
[Title("DynamicUI相关-Simple")]
public GameObject dynamicUIContainer;
public GameObject inputField;
@@ -58,8 +58,12 @@ public class BasePrefabsCollection : SerializedScriptableObject
public GameObject animatedBoolUnit;
public GameObject customCurveKeyframeUnit;
public GameObject customCurveWrapModeUnit;
[Title("Background相关")]
[Title("图形化动画编辑器")]
public GameObject graphicalFlexibleFloatWindow;
//采音器
[Title("Background相关")]
public Sprite defaultBackground;
public Material defaultSkyboxMaterial;
}