using System; using System.Collections; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Dreamteck.Splines; using Ichni; using Ichni.Editor; using Ichni.RhythmGame; using TMPro; using Unity.VisualScripting; using UnityEngine; using UnityEngine.EventSystems; 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; 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(0, 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 (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, float posx = 0) { GameObject u = Instantiate(NotePrefab, NoteMovepoint); u.GetComponent().Initialize(i, timePerBeat, beatDeviver); } public GameObject selectedGameObject; void Update() { selectedGameObject = EventSystem.current.currentSelectedGameObject; 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; } if (selectedGameObject is null && RectTransformUtility.RectangleContainsScreenPoint(windowRect, Mouse.current.position.ReadValue())) { DetectNote(); } } 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 DetectNote() { if (Keyboard.current.digit1Key.wasPressedThisFrame) AddNote(0); else if (Keyboard.current.digit2Key.wasPressedThisFrame) AddNote(1); else if (Keyboard.current.digit3Key.wasPressedThisFrame) AddNote(2); else if (Keyboard.current.digit4Key.wasPressedThisFrame) AddNote(3); } public void AddNote(int NoteCode) { // 获取鼠标在 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 { switch (NoteCode) { case 0: Tap a = Tap.GenerateElement("New Tap", Guid.NewGuid(), new List(), false, gameElement, time); noteBases.Add(a); SpawnNote(a); break; case 3: Hold b = Hold.GenerateElement("New Hold", Guid.NewGuid(), new List(), false, gameElement, time, time + 0.5f); noteBases.Add(b); SpawnNote(b); break; case 1: Stay c = Stay.GenerateElement("New Stay", Guid.NewGuid(), new List(), false, gameElement, time); noteBases.Add(c); SpawnNote(c); break; case 2: Flick d = Flick.GenerateElement("New Flick", Guid.NewGuid(), new List(), false, gameElement, time, new List()); noteBases.Add(d); SpawnNote(d); break; } } } }