using System.Collections; using System.Collections.Generic; using System.Linq; using DG.Tweening; using Ichni; using Ichni.Editor; using Ichni.RhythmGame; using Sirenix.OdinInspector; using Sirenix.Utilities; using TMPro; using UnityEngine; using UnityEngine.Events; using UnityEngine.InputSystem; using UnityEngine.UI; public partial class GraphicalFlexibleFloatWindow : MovableWindow { public FlexibleFloatTab unitPrefab; public IBaseElement connectedBaseElement; public List unitList; 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 int BeatNextDeviver = 1; public void Initialize(IBaseElement baseElement, string title, FlexibleFloat[] FlexibleFloats, string[] Subtitles) { InitializeWindow(title, null, new Vector3(1f, 1f, 1f)); scalevalue = 5; this.connectedBaseElement = baseElement; this.title.text = title; unitList = new List(); closeButton.onClick.AddListener(Quit); for (int i = 0; i <= FlexibleFloats.Length - 1; i++) { ClipBoard.Add(Subtitles[i], new List()); AddUnit(FlexibleFloats[i], Subtitles[i]); } ApplyParameters = () => { for (int i = 0; i <= unitList.Count - 1; i++) { unitList[i].connectFloat.Sort(); } }; XDeviverScale("1"); EvEndpointChangeButton.onClick.AddListener(EvEndpointStartChange); GetComponent().sizeDelta = new Vector2(1400, (FlexibleFloats.Length + 1) * 200 + 50); } 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)); this.transform.DOScale(Vector3.zero, 0.15f).SetEase(Ease.InCirc).OnComplete(() => { Destroy(gameObject); }); } public float scalevalue; public void CurveScale(string Rawvalue) { float value = float.Parse(Rawvalue); scalevalue = value; foreach (FlexibleFloatTab i in unitList) { i.CurveScale(value); } } public void DeviverScale(string Rawvalue) { if (ConnectedPoint != null) ConnectedPoint.UpLoad(); BeatDeviver = int.Parse(Rawvalue); ChangeValue(); for (int i = unitList.Count - 1; i >= 0; i--) { unitList[i].Initialize(unitList[i].connectFloat, unitList[i].Title); } XDeviverScale(BeatNextDeviver.ToString()); } public void XDeviverScale(string Rawvalue) { BeatNextDeviver = int.Parse(Rawvalue); foreach (FlexibleFloatTab i in unitList) { i.XbeatCnange(BeatNextDeviver); } } } public partial class GraphicalFlexibleFloatWindow { [Title("AnimEditor")] public TMP_InputField StartText; public TMP_InputField EndText; public TMP_InputField StartValueText; public TMP_InputField EndValueText; public TMP_InputField EventMultiplier; public EventPoint ConnectedPoint; public TMP_Dropdown animationCurveTypeDropdown; public GameObject VisibleArea; /// /// 移除当前连接的事件点,并更新 UI。 /// public void RemoveConnectedPoint() { if (ConnectedPoint != null) { // 调用 FlexibleFloatTab 的 RemoveEventPoint 方法 ConnectedPoint.FatherTab.RemoveEventPoint(ConnectedPoint); // 清空连接点并隐藏可见区域 ConnectedPoint = null; VisibleArea.SetActive(false); } } public void ChangeValue() { if (ConnectedPoint != null) { float startTime = float.Parse(StartText.text); float endTime = float.Parse(EndText.text); float startValue = float.Parse(StartValueText.text); float endValue = float.Parse(EndValueText.text); ConnectedPoint.animatedFloat.startTime = startTime; ConnectedPoint.animatedFloat.endTime = endTime; ConnectedPoint.animatedFloat.startValue = startValue; ConnectedPoint.animatedFloat.endValue = endValue; ConnectedPoint.animatedFloat.animationCurveType = (AnimationCurveType)animationCurveTypeDropdown.value; ConnectedPoint.Initialize(ConnectedPoint.animatedFloat); ConnectedPoint.ReDraw(scalevalue); } } public Button EvEndpointChangeButton; public void EvEndpointStartChange() { if (ConnectedPoint != null) { EndText.text = (ConnectedPoint.animatedFloat.startTime + 0.01).ToString(); ChangeValue(); EvEndpointChangeButton.GetComponent().color = new Color(1f, 0.5f, 0.5f, 1); ConnectedPoint.FatherTab.TabButton.onClick.RemoveAllListeners(); ConnectedPoint.FatherTab.TabButton.onClick.AddListener(EvEndpointEndChange); } } public void EvEndpointEndChange() { if (ConnectedPoint != null) { EvEndpointChangeButton.GetComponent().color = new Color(1f, 1f, 1f, 1); float newendtime = ConnectedPoint.FatherTab.GetBeat(); if (newendtime > ConnectedPoint.animatedFloat.startTime) { if (ConnectedPoint.NextEventPoint != null && newendtime > ConnectedPoint.NextEventPoint.animatedFloat.startTime) EndText.text = ConnectedPoint.NextEventPoint.animatedFloat.startTime.ToString(); else EndText.text = newendtime.ToString(); ChangeValue(); } ConnectedPoint.FatherTab.TabButton.onClick.RemoveAllListeners(); } } public Dictionary> ClipBoard = new(); public void Update() { if (Keyboard.current.deleteKey.isPressed && ConnectedPoint != null) { RemoveConnectedPoint(); } if (Keyboard.current.shiftKey.isPressed) { if (Keyboard.current.vKey.wasPressedThisFrame) PasteClipboard(1f); else if (Keyboard.current.bKey.wasPressedThisFrame) PasteClipboard(-1f); } if (Keyboard.current.escapeKey.wasPressedThisFrame) { foreach (var key in ClipBoard.Keys.ToList()) { ClipBoard[key] = new List(); } foreach (FlexibleFloatTab i in unitList) { foreach (EventPoint j in i.eventPoints) { j.LeftSide.sizeDelta = new Vector2(15, j.EvDrawimage.rectTransform.sizeDelta.y); } } updateClipBoardMuM(); } if (ConnectedPoint != null && RectTransformUtility.RectangleContainsScreenPoint(GetComponent(), Mouse.current.position.ReadValue())) { if (Keyboard.current.aKey.wasPressedThisFrame) { ConnectedPoint.animatedFloat.endValue *= -1; ConnectedPoint.animatedFloat.startValue *= -1; ConnectedPoint.Refresh(); } else if (Keyboard.current.sKey.wasPressedThisFrame) { float value = ConnectedPoint.animatedFloat.startValue; ConnectedPoint.animatedFloat.startValue = ConnectedPoint.animatedFloat.endValue; ConnectedPoint.animatedFloat.endValue = value; ConnectedPoint.Refresh(); } else if (Keyboard.current.uKey.wasPressedThisFrame) { try { ConnectedPoint.FatherTab.StartCoroutine(ConnectedPoint.FatherTab.Draging()); } catch (System.Exception) { EventPoint.Locked = false; } } else if (Keyboard.current.lKey.wasPressedThisFrame) { ConnectedPoint.FatherTab.CutEvent(); } } } public void PasteClipboard(float valuescale = 1f) { // 获取当前时间线的节拍位置 float time = unitList[0].GetBeat(); float MinCopyTime = float.MaxValue; // 遍历剪贴板中的所有动画数据MinCopyTime = float.MaxValue; foreach (var list in ClipBoard.Values) { foreach (var animatedFloat in list) { if (animatedFloat.startTime < MinCopyTime) { MinCopyTime = animatedFloat.startTime; } } } foreach (var key in ClipBoard.Keys) { foreach (var animatedFloat in ClipBoard[key]) { // 克隆动画数据并应用时间偏移 AnimatedFloat newFloat = EventPoint.CloneWithOffset(animatedFloat, time - MinCopyTime); newFloat.startValue *= valuescale; newFloat.endValue *= valuescale; // 在对应的 FlexibleFloatTab 中生成事件点 unitList.Find(x => x.Title == key).SpawnEvent(newFloat); } } } } public partial class GraphicalFlexibleFloatWindow {//以后显示类写这里,别在叠大粪了 public TMP_Text ClipBoardMuM; public void updateClipBoardMuM() { int mum = 0; foreach (var key in ClipBoard.Keys) { mum += ClipBoard[key].Count(); } ClipBoardMuM.text = "ClipBoard: " + mum.ToString(); } }