using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Dreamteck.Splines; using Ichni; using Ichni.Editor; using Ichni.RhythmGame; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.InputSystem; using UnityEngine.UI; public class SampleWindow : MovableWindow//该window高度为300,横的要在100和500之间切换 { public static List instances = new List(); public TMP_InputField DeviverInputField; public TMP_InputField verticalInputField; public TMP_InputField horizontalInputField; public RectTransform LineMovepoint; public RectTransform NoteMovepoint; public List noteBases; public bool isFocus = false; public bool isExpand = false; public int beatDeviver = 100; public int Xdevide = 1; public float realDevider; public GameObject beatLinePrefabv; public GameObject beatLinePrefabh; public GameObject NotePrefab; public RectTransform secBeatLineh;//用于定位屏幕位置 float songTime => EditorManager.instance.songInformation.songTime; float songBeat => EditorManager.instance.songInformation.songBeat; float beatmapStartTime => -EditorManager.instance.songInformation.delay; float timePerBeat => 60f / EditorManager.instance.songInformation.bpm; public GameElement gameElement; public SplinePositioner trackPositioner = null; public GameObject trackHead; public void Initialize(GameElement qgameElement, string title) { closeButton.onClick.AddListener(() => { instances.Remove(this); }); if (instances.Where(i => i.gameElement == qgameElement).Count() != 0) { Destroy(this.gameObject); foreach (SampleWindow i in instances) { i.StartCoroutine(WindowAnim.Shake(instances.Where(i => i.gameElement == qgameElement).First().windowRect.gameObject)); } return; } this.gameElement = qgameElement; if (qgameElement is Track track) { trackPositioner = this.gameObject.AddComponent(); trackPositioner.spline = track.trackPathSubmodule.path; trackPositioner.enabled = isFocus; trackPositioner.targetObject = trackHead; } InitializeWindow(title); // SpawnBeatline(); OnceSpawnNote(); instances.Add(this); } public void SpawnBeatline()//添加优化措施 { for (int i = LineMovepoint.childCount - 1; i >= 0; i--) { Destroy(LineMovepoint.GetChild(i).gameObject); } for (int i = 0; i < (int)EditorManager.instance.songInformation.song.length / timePerBeat; i++) { for (int j = 1; j < Xdevide; j++) { GameObject v = Instantiate(beatLinePrefabh, LineMovepoint); v.transform.localPosition = new Vector3(0, i * beatDeviver + (beatDeviver / Xdevide * j), 0); RawImage g = v.GetComponent(); g.color = new Color(g.color.r, g.color.g, g.color.b, 0.2f); if (v.transform.localPosition.y > 600) { Destroy(v); break; } } GameObject u = Instantiate(beatLinePrefabh, LineMovepoint); u.transform.localPosition = new Vector3(0, i * beatDeviver, 0); if (i == 1) { secBeatLineh = u.GetComponent(); realDevider = secBeatLineh.position.y - LineMovepoint.position.y; Debug.Log(realDevider); } if (u.transform.localPosition.y > 600) { Destroy(u); break; } } } public void OnceSpawnNote() { if (gameElement is Track track) noteBases = track.GetAllNotes(); else if (gameElement is ElementFolder elementFolder) noteBases = elementFolder.GetAllNotes(); for (int i = NoteMovepoint.childCount - 1; i >= 0; i--) { Destroy(NoteMovepoint.GetChild(i).gameObject); } foreach (var i in noteBases) { SpawnNote(i); } } private void SpawnNote(NoteBase i) { GameObject u = Instantiate(NotePrefab, NoteMovepoint); u.transform.localPosition = new Vector3(0, i.exactJudgeTime / timePerBeat * beatDeviver, 0); Image color = u.GetComponent(); u.GetComponent().noteBase = i; switch (i) { case Hold hold: color.color = new Color(0, 1, 0, 1); RawImage a = u.GetComponent(); a.transform.localPosition = new Vector3(0, (hold.holdEndTime - hold.exactJudgeTime) / timePerBeat * beatDeviver / 2, 0); a.GetComponent().sizeDelta = new Vector2(0, (hold.holdEndTime - hold.exactJudgeTime) / timePerBeat * beatDeviver); break; case Tap: color.color = new Color(0, 1, 1, 1); break; case Stay: color.color = new Color(1, 1, 0, 1); break; case Flick: color.color = new Color(1, 0.2f, 0, 1); break; }//服了,之后整合到controler里头去 } void Update() { LineMovepoint.localPosition = new(0, -beatDeviver * (songBeat - (int)songBeat), 0); NoteMovepoint.localPosition = new(0, -beatDeviver * songBeat, 0); if (isFocus && gameElement is Track track) { if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable) { trackPositioner.SetPercent(track.trackTimeSubmodule.headPercent); windowRect.GetComponent().alpha = (songTime >= trackTimeSubmoduleMovable.trackStartTime && songTime <= trackTimeSubmoduleMovable.trackEndTime) ? 1f : 0.2f; } else if (track.trackTimeSubmodule is TrackTimeSubmoduleStatic) { trackPositioner.SetPercent(0f); } TransformChanged(); windowRect.GetComponent().alpha = track.timeDurationSubmodule.CheckTimeInDuration(songTime) ? 1f : 0.2f; } } void TransformChanged() { RectTransform canvasRect = EditorManager.instance.inspectorCanvas.GetComponent(); Vector2 ScreenPosition = EditorManager.instance.cameraManager.currentCamera.WorldToScreenPoint(trackHead.transform.position); if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, ScreenPosition, null, out Vector2 uiPosition)) { windowRect.anchoredPosition = new Vector2(uiPosition.x, uiPosition.y + 150f); } } public void ChangeFocus() { isFocus = !isFocus; if (trackPositioner != null) trackPositioner.enabled = isFocus; } public void ChangeXdevide(string devide) { Xdevide = int.Parse(devide); SpawnBeatline(); } public void ChangeBeatdevide(string devide) { beatDeviver = int.Parse(devide); SpawnBeatline(); OnceSpawnNote(); } public void ChangeExpand() { if (isExpand) { isExpand = false; windowRect.sizeDelta = new Vector2(100, windowRect.sizeDelta.y); } else { isExpand = true; windowRect.sizeDelta = new Vector2(500, windowRect.sizeDelta.y); } } public void AddNote() { // 获取鼠标在 NoteMovepoint 中的相对位置 Vector2 localMousePosition = NoteMovepoint.InverseTransformPoint(Mouse.current.position.ReadValue()); Debug.Log(localMousePosition); float mouseBeat = localMousePosition.y / beatDeviver; float far = 0f; while (far < mouseBeat) { far += 1f / Xdevide; } far -= 1f / Xdevide; float time = far * timePerBeat; if (!isExpand)//movable { Tap a = Tap.GenerateElement("New Tap", Guid.NewGuid(), new List(), true, gameElement, time); noteBases.Add(a); SpawnNote(a); } } }