using System.Collections; using System.Collections.Generic; using System.Linq; using Ichni; using Ichni.RhythmGame; using TMPro; using UnityEngine; using UnityEngine.InputSystem; 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 RawImage CurveCanvas; public FlexibleFloatTab FatherTab; public TMP_Text ViewText; 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 - LeftSide.localPosition.x, EvDrawimage.rectTransform.sizeDelta.y); EvDrawimage.transform.localPosition = new Vector3(EvDrawimage.rectTransform.sizeDelta.x / 2, 0, 0); OvDrawimage.transform.localPosition = RightSide.localPosition; CurveCanvas.rectTransform.sizeDelta = new Vector2(EvDrawimage.rectTransform.sizeDelta.x, EvDrawimage.rectTransform.sizeDelta.y); } public float value => FatherTab.scalevalue; public void ReDraw(float value) { Texture2D Texture = new Texture2D((int)CurveCanvas.rectTransform.sizeDelta.x / 5, (int)CurveCanvas.rectTransform.sizeDelta.y / 5); for (int i = 0; i < Texture.width; i++) { for (int j = 0; j < Texture.height; j++) { Texture.SetPixel(i, j, new Color(0, 0, 0, 0)); } } Texture.Apply(); int LastEventPointY = 0; for (int i = 0; i < Texture.width; i++) { float t = (float)i / Texture.width; int f = (int)( (Texture.height / 2) + (animatedFloat.startValue * value + ((animatedFloat.endValue - animatedFloat.startValue) * AnimationCurveEvaluator.Evaluate(animatedFloat.animationCurveType, t) * value)) ); //不是哥们 for (int j = LastEventPointY; j < f; j++) { if (j < Texture.height) Texture.SetPixel(i, j, Color.green); else Texture.SetPixel(i, j, Color.red); } for (int j = LastEventPointY; j > f; j--) { if (j > 0) Texture.SetPixel(i, j, Color.green); else Texture.SetPixel(i, j, Color.red); } if (f < Texture.height && f > 0) Texture.SetPixel(i, f, Color.green);//丑陋 else Texture.SetPixel(i, f, Color.red); LastEventPointY = f; } Texture.Apply(); CurveCanvas.texture = Texture; if (NextEventPoint != null) { OvDrawimage.transform.localPosition = new Vector3(RightSide.transform.localPosition.x, animatedFloat.endValue * value * 5, 0); OvDrawimage.rectTransform.sizeDelta = new Vector2((NextEventPoint.animatedFloat.startTime - animatedFloat.endTime) / EditorManager.instance.uiManager.timeline.timePerBeat * FatherTab.BeatDeviver, OvDrawimage.rectTransform.sizeDelta.y); OvDrawimage.color = new Color(0, 1, 0, 1); while (OvDrawimage.transform.localPosition.y > 100) { OvDrawimage.color = new Color(1, 0, 0, 0.3f); OvDrawimage.transform.localPosition = new Vector3(OvDrawimage.transform.localPosition.x, OvDrawimage.transform.localPosition.y - 200, OvDrawimage.transform.localPosition.z); } while (OvDrawimage.transform.localPosition.y < -100) { OvDrawimage.color = new Color(1, 0, 0, 0.3f); OvDrawimage.transform.localPosition = new Vector3(OvDrawimage.transform.localPosition.x, OvDrawimage.transform.localPosition.y + 200, OvDrawimage.transform.localPosition.z); } } else { OvDrawimage.rectTransform.sizeDelta = new Vector2(0, OvDrawimage.rectTransform.sizeDelta.y ); } selectButton.transform.localPosition = EvDrawimage.transform.localPosition; selectButton.GetComponent().sizeDelta = EvDrawimage.rectTransform.sizeDelta; ViewText.text = animatedFloat.startTime.ToString("0.00") + "s" + "\n" + animatedFloat.startValue.ToString("0.0") + "\n" + animatedFloat.endValue.ToString("0.0") + "\n" + animatedFloat.endTime.ToString("0.00") + "s" + "\n" + animatedFloat.animationCurveType.ToString(); ViewText.color = new Color(1, 1, 1, EvDrawimage.rectTransform.sizeDelta.x < 100 ? 0 : 1); } private void Update() { if (RectTransformUtility.RectangleContainsScreenPoint(CurveCanvas.GetComponent(), Mouse.current.position.ReadValue())) { } } public void SelectButtonClick()//unity内:当按钮按下时 { if (Keyboard.current.leftShiftKey.isPressed) { if (FatherTab.FatherWindow.ClipBoard[FatherTab.Title].Contains(animatedFloat)) { FatherTab.FatherWindow.ClipBoard[FatherTab.Title].Remove(animatedFloat); LeftSide.sizeDelta = new Vector2(15, EvDrawimage.rectTransform.sizeDelta.y); } else { FatherTab.FatherWindow.ClipBoard[FatherTab.Title].Add(animatedFloat); LeftSide.sizeDelta = EvDrawimage.rectTransform.sizeDelta; } FatherTab.FatherWindow.updateClipBoardMuM(); } else UpLoad(); } public void UpLoad() { FatherTab.FatherWindow.animationCurveTypeDropdown.onValueChanged.RemoveAllListeners(); // 如果当前点是已连接点,则取消连接并隐藏可见区域 if (FatherTab.FatherWindow.ConnectedPoint == this) { FatherTab.FatherWindow.VisibleArea.SetActive(false); FatherTab.FatherWindow.ConnectedPoint = null; EvDrawimage.color = new Color(EvDrawimage.color.r, 0.3019607843137255f, EvDrawimage.color.b, 0.5f); FatherTab.FatherWindow.StartText.text = ""; FatherTab.FatherWindow.EndText.text = ""; FatherTab.FatherWindow.StartValueText.text = ""; FatherTab.FatherWindow.EndValueText.text = ""; return; } // 如果有已连接点,则重置其颜色 if (FatherTab.FatherWindow.ConnectedPoint != null) { FatherTab.FatherWindow.EvEndpointChangeButton.GetComponent().color = new Color(1f, 1f, 1f, 1); FatherTab.FatherWindow.ConnectedPoint.EvDrawimage.color = new Color( FatherTab.FatherWindow.ConnectedPoint.EvDrawimage.color.r, 0.3019607843137255f, FatherTab.FatherWindow.ConnectedPoint.EvDrawimage.color.b, 0.5f ); } // 设置新的连接点并更新UI FatherTab.FatherWindow.ConnectedPoint = this; EvDrawimage.color = new Color(EvDrawimage.color.r, 0.75f, EvDrawimage.color.b, 1f); // 更新下拉选项 FatherTab.FatherWindow.animationCurveTypeDropdown.ClearOptions(); List enumNameList = System.Enum.GetNames(typeof(AnimationCurveType)).ToList(); FatherTab.FatherWindow.VisibleArea.SetActive(true); FatherTab.FatherWindow.animationCurveTypeDropdown.AddOptions(enumNameList); FatherTab.FatherWindow.animationCurveTypeDropdown.value = (int)animatedFloat.animationCurveType; // 更新文本 FatherTab.FatherWindow.StartText.text = animatedFloat.startTime.ToString(); FatherTab.FatherWindow.EndText.text = animatedFloat.endTime.ToString(); FatherTab.FatherWindow.StartValueText.text = animatedFloat.startValue.ToString(); FatherTab.FatherWindow.EndValueText.text = animatedFloat.endValue.ToString(); FatherTab.FatherWindow.animationCurveTypeDropdown.onValueChanged.AddListener(value => FatherTab.FatherWindow.ChangeValue()); } // 添加静态方法:查找插入索引 public static int FindInsertIndex(List eventPoints, float startTime) { int low = 0; int high = eventPoints.Count - 1; while (low <= high) { int mid = (low + high) / 2; if (eventPoints[mid].animatedFloat.startTime < startTime) { low = mid + 1; } else { high = mid - 1; } } return low; } // 添加实例方法:连接事件点 public void LinkEventPoints(List eventPoints, int index) { if (index - 1 >= 0) { LastEventPoint = eventPoints[index - 1]; LastEventPoint.NextEventPoint = this; } else { LastEventPoint = null; } if (index == eventPoints.Count - 1) { NextEventPoint = null; } } // 添加实例方法:连接新事件点 public void LinkNewEventPoint(List eventPoints, bool link, float scalevalue) { int index = eventPoints.IndexOf(this); if (index - 1 >= 0) { LastEventPoint = eventPoints[index - 1]; LastEventPoint.NextEventPoint = this; LastEventPoint.ReDraw(scalevalue); } if (index + 1 < eventPoints.Count) { NextEventPoint = eventPoints[index + 1]; if (link) animatedFloat.endTime = NextEventPoint.animatedFloat.startTime; Initialize(animatedFloat); NextEventPoint.LastEventPoint = this; } } // 添加静态方法:克隆 AnimatedFloat 并应用时间偏移 /// /// 克隆一个 AnimatedFloat 对象,并根据偏移量调整其开始和结束时间。 /// /// 要克隆的 AnimatedFloat 对象。 /// 时间偏移量。 /// 克隆后的 AnimatedFloat 对象。 public static AnimatedFloat CloneWithOffset(AnimatedFloat animatedFloat, float offset) { return new AnimatedFloat( animatedFloat.startTime + offset, animatedFloat.endTime + offset, animatedFloat.startValue, animatedFloat.endValue, animatedFloat.animationCurveType ); } }