using System.Collections; using System.Collections.Generic; using System.Data; using System.Linq; using Ichni; using Ichni.Editor; using Ichni.RhythmGame; using Unity.VisualScripting; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; public class FlexibleFloatTab : MonoBehaviour { public GraphicalFlexibleFloatWindow FatherWindow; public List eventPoints; public RectTransform Area; public RectTransform BeatArea; public RectTransform XBeatArea; public EventPoint eventPoint; public GameObject BeatLine; public Button TabButton; public string Title; public FlexibleFloat connectFloat; public int BeatDeviver => FatherWindow.BeatDeviver; public int BeatNextDeviver => FatherWindow.BeatNextDeviver; // 初始化函数 public void Initialize(FlexibleFloat flexibleFloat, string title) { Title = title; ClearChildren(Area); ClearChildren(BeatArea); eventPoints = new List(); connectFloat = flexibleFloat; CreateBeatLines(); CreateEventPoints(); Area.localPosition = new Vector3(FatherWindow.songBeat * BeatDeviver, 0, 0); TabButton.onClick.AddListener(AddEvent); } // 清除子节点 private void ClearChildren(RectTransform parent) { for (int i = 0; i < parent.childCount; i++) { Destroy(parent.GetChild(i).gameObject); } } // 创建节拍线 private void CreateBeatLines() { // 先清空BeatArea下的所有子对象,防止重复生成 for (int i = BeatArea.childCount - 1; i >= 0; i--) { Destroy(BeatArea.GetChild(i).gameObject); } float maxX = 1400f + (3 * BeatDeviver); int totalBeats = (int)(EditorManager.instance.songInformation.song.length / FatherWindow.timePerBeat); for (int i = 0; i < totalBeats; i++) { float posX = BeatDeviver * i; if (posX > maxX) { break; } GameObject u = Instantiate(BeatLine, BeatArea); u.transform.localPosition = new Vector3(posX, 0, 0); } } // 创建事件点 private void CreateEventPoints() { for (int i = 0; i <= connectFloat.animations.Count - 1; i++) { AnimatedFloat animatedFloat = connectFloat.animations[i]; EventPoint eventPoint = Instantiate(this.eventPoint, Area); eventPoint.FatherTab = this; eventPoint.Initialize(animatedFloat); eventPoints.Add(eventPoint); LinkEventPoints(i, eventPoint); } foreach (var i in eventPoints) { i.ReDraw(scalevalue); } } // 更新函数 public void Update() { Vector3 newPosition = new Vector3(-FatherWindow.songBeat * BeatDeviver, 0, 0); Area.localPosition = newPosition; BeatArea.localPosition = newPosition; while (true) { BeatArea.localPosition += new Vector3(BeatDeviver, 0, 0); if (BeatArea.localPosition.x > ((-200f) - BeatDeviver)) { break; } } XBeatArea.localPosition = BeatArea.localPosition; } // 添加事件 public void AddEvent() { if (Keyboard.current.ctrlKey.isPressed) { EventPoint eventPoint = Instantiate(this.eventPoint, Area); eventPoint.FatherTab = this; eventPoint.Initialize(new AnimatedFloat(GetBeat(), GetBeat() + (float.Parse(FatherWindow.EventMultiplier.text) * FatherWindow.timePerBeat), 0, 0, AnimationCurveType.Linear)); eventPoints.Insert(FindInsertIndex(eventPoint.animatedFloat.startTime), eventPoint); LinkNewEventPoint(eventPoint, true); eventPoint.ReDraw(scalevalue); eventPoint.selectButton.onClick.Invoke(); FatherWindow.ChangeValue(); connectFloat.Add(eventPoint.animatedFloat); connectFloat.Sort(); } else { if (FatherWindow.ConnectedPoint != null) FatherWindow.ConnectedPoint.UpLoad(); } } public void SpawnEvent(AnimatedFloat animatedFloat) { EventPoint eventPoint = Instantiate(this.eventPoint, Area); eventPoint.FatherTab = this; eventPoint.Initialize(animatedFloat); eventPoints.Insert(FindInsertIndex(eventPoint.animatedFloat.startTime), eventPoint); LinkNewEventPoint(eventPoint); eventPoint.ReDraw(scalevalue); connectFloat.Add(eventPoint.animatedFloat); connectFloat.Sort(); } // 添加调用 EventPoint 类的接口 public void LinkEventPoints(int index, EventPoint eventPoint) { eventPoint.LinkEventPoints(eventPoints, index); } public void LinkNewEventPoint(EventPoint eventPoint, bool link = false) { eventPoint.LinkNewEventPoint(eventPoints, link, scalevalue); } public int FindInsertIndex(float startTime) { return EventPoint.FindInsertIndex(eventPoints, startTime); } // 获取节拍 public float GetBeat() { // 获取鼠标在 BeatArea 中的相对位置 Vector2 localMousePosition = Area.InverseTransformPoint(Mouse.current.position.ReadValue()); //Debug.Log(localMousePosition); float mouseBeat = localMousePosition.x / BeatDeviver; float far = 0f; while (far < mouseBeat) { far += 1f / BeatNextDeviver; } far -= 1f / BeatNextDeviver; return far * FatherWindow.timePerBeat; } public float scalevalue => FatherWindow.scalevalue; // 曲线缩放 public void CurveScale(float value) { foreach (EventPoint i in eventPoints) { i.ReDraw(value); } } // 改变X轴节拍 public void XbeatCnange(int num) { ClearChildren(XBeatArea); for (int i = 1; i < num; i++) { foreach (Transform child in BeatArea) { GameObject newChild = Instantiate(child.gameObject, XBeatArea); CanvasGroup canvasGroup = newChild.GetComponent(); newChild.transform.localPosition = new Vector3(child.localPosition.x + ((float)BeatDeviver) / num * i, child.localPosition.y, child.localPosition.z); if (canvasGroup == null) { canvasGroup = newChild.AddComponent(); } canvasGroup.alpha = 0.1f; } } } // 移除动画 public void remoceAnim(AnimatedFloat a) { if (connectFloat.animations.Contains(a)) { connectFloat.animations.Remove(a); } } /// /// 从事件点列表中移除指定的事件点,并更新其前后连接关系。 /// /// 要移除的事件点。 public void RemoveEventPoint(EventPoint eventPoint) { if (eventPoints.Contains(eventPoint)) { // 更新前后事件点的连接关系 if (eventPoint.LastEventPoint != null) { eventPoint.LastEventPoint.NextEventPoint = eventPoint.NextEventPoint; eventPoint.LastEventPoint.ReDraw(scalevalue); } if (eventPoint.NextEventPoint != null) { eventPoint.NextEventPoint.LastEventPoint = eventPoint.LastEventPoint; eventPoint.NextEventPoint.ReDraw(scalevalue); } // 从列表中移除事件点 eventPoints.Remove(eventPoint); // 从连接的动画中移除 connectFloat.animations.Remove(eventPoint.animatedFloat); // 销毁事件点对象 Destroy(eventPoint.gameObject); } } }