2025-05-01 22:54:56 +08:00
|
|
|
|
using System;
|
|
|
|
|
|
using System.Collections;
|
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
using System.Linq;
|
2025-05-11 00:20:27 +08:00
|
|
|
|
using System.Text.RegularExpressions;
|
2025-05-02 22:34:42 +08:00
|
|
|
|
using Dreamteck.Splines;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
using Ichni;
|
|
|
|
|
|
using Ichni.Editor;
|
|
|
|
|
|
using Ichni.RhythmGame;
|
|
|
|
|
|
using TMPro;
|
|
|
|
|
|
using Unity.VisualScripting;
|
|
|
|
|
|
using UnityEngine;
|
2025-05-11 00:20:27 +08:00
|
|
|
|
using UnityEngine.EventSystems;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
using UnityEngine.InputSystem;
|
|
|
|
|
|
using UnityEngine.UI;
|
|
|
|
|
|
|
2025-07-17 16:44:38 +08:00
|
|
|
|
public class SampleWindow : MovableWindow//该window高度为300,横的要XWidth0和500之间切换
|
2025-05-01 22:54:56 +08:00
|
|
|
|
{
|
|
|
|
|
|
public static List<SampleWindow> instances = new List<SampleWindow>();
|
|
|
|
|
|
public TMP_InputField DeviverInputField;
|
|
|
|
|
|
public TMP_InputField verticalInputField;
|
|
|
|
|
|
public TMP_InputField horizontalInputField;
|
|
|
|
|
|
public RectTransform LineMovepoint;
|
|
|
|
|
|
public RectTransform NoteMovepoint;
|
|
|
|
|
|
|
|
|
|
|
|
public List<NoteBase> noteBases;
|
|
|
|
|
|
public bool isFocus = false;
|
|
|
|
|
|
public bool isExpand = false;
|
|
|
|
|
|
public int beatDeviver = 100;
|
2025-07-17 16:44:38 +08:00
|
|
|
|
public int XWidth = 10;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
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;
|
2025-05-02 22:34:42 +08:00
|
|
|
|
public SplinePositioner trackPositioner = null;
|
|
|
|
|
|
public GameObject trackHead;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
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;
|
2025-05-02 22:34:42 +08:00
|
|
|
|
if (qgameElement is Track track)
|
|
|
|
|
|
{
|
|
|
|
|
|
trackPositioner = this.gameObject.AddComponent<SplinePositioner>();
|
|
|
|
|
|
trackPositioner.spline = track.trackPathSubmodule.path;
|
|
|
|
|
|
trackPositioner.enabled = isFocus;
|
|
|
|
|
|
trackPositioner.targetObject = trackHead;
|
|
|
|
|
|
}
|
2025-05-01 22:54:56 +08:00
|
|
|
|
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++)
|
|
|
|
|
|
{
|
|
|
|
|
|
|
2025-05-02 22:34:42 +08:00
|
|
|
|
|
|
|
|
|
|
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<RawImage>();
|
2025-05-11 00:20:27 +08:00
|
|
|
|
g.color = new Color(0, g.color.g, g.color.b, 0.2f);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
if (v.transform.localPosition.y > 1200)
|
2025-05-02 22:34:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
Destroy(v);
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-05-01 22:54:56 +08:00
|
|
|
|
GameObject u = Instantiate(beatLinePrefabh, LineMovepoint);
|
|
|
|
|
|
u.transform.localPosition = new Vector3(0, i * beatDeviver, 0);
|
2025-05-30 19:37:54 +08:00
|
|
|
|
|
2025-05-02 22:34:42 +08:00
|
|
|
|
if (u.transform.localPosition.y > 600)
|
2025-05-01 22:54:56 +08:00
|
|
|
|
{
|
|
|
|
|
|
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)
|
|
|
|
|
|
{
|
2025-07-17 16:44:38 +08:00
|
|
|
|
SpawnNote(i, i.noteVisual.transformSubmodule.originalPosition.x * XWidth);
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-05-11 00:20:27 +08:00
|
|
|
|
private void SpawnNote(NoteBase i, float posx = 0)
|
2025-05-01 22:54:56 +08:00
|
|
|
|
{
|
|
|
|
|
|
GameObject u = Instantiate(NotePrefab, NoteMovepoint);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
u.GetComponent<NotefabContoler>().Initialize(i, timePerBeat, beatDeviver, posx);
|
|
|
|
|
|
u.GetComponent<NotefabContoler>().sampleWindow = this;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2025-05-11 14:12:47 +08:00
|
|
|
|
public GameObject selectedGameObject;
|
2025-05-11 00:20:27 +08:00
|
|
|
|
void Update()
|
2025-05-01 22:54:56 +08:00
|
|
|
|
{
|
2025-05-11 00:20:27 +08:00
|
|
|
|
selectedGameObject = EventSystem.current.currentSelectedGameObject;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
LineMovepoint.localPosition = new(0, -beatDeviver * (songBeat - (int)songBeat), 0);
|
|
|
|
|
|
NoteMovepoint.localPosition = new(0, -beatDeviver * songBeat, 0);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
|
|
|
|
|
|
if (RectTransformUtility.RectangleContainsScreenPoint(windowRect, Mouse.current.position.ReadValue()))
|
|
|
|
|
|
{
|
|
|
|
|
|
DetectNote();
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
void LateUpdate()
|
|
|
|
|
|
{
|
2025-05-01 22:54:56 +08:00
|
|
|
|
if (isFocus && gameElement is Track track)
|
|
|
|
|
|
{
|
2025-05-03 14:25:04 +08:00
|
|
|
|
if (track.trackTimeSubmodule is TrackTimeSubmoduleMovable trackTimeSubmoduleMovable)
|
2025-05-02 22:34:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
trackPositioner.SetPercent(track.trackTimeSubmodule.headPercent);
|
2025-05-03 14:25:04 +08:00
|
|
|
|
windowRect.GetComponent<CanvasGroup>().alpha = (songTime >= trackTimeSubmoduleMovable.trackStartTime && songTime <= trackTimeSubmoduleMovable.trackEndTime) ? 1f : 0.2f;
|
|
|
|
|
|
|
2025-05-02 22:34:42 +08:00
|
|
|
|
}
|
2025-05-03 14:25:04 +08:00
|
|
|
|
else if (track.trackTimeSubmodule is TrackTimeSubmoduleStatic)
|
2025-05-02 22:34:42 +08:00
|
|
|
|
{
|
|
|
|
|
|
trackPositioner.SetPercent(0f);
|
|
|
|
|
|
}
|
|
|
|
|
|
TransformChanged();
|
|
|
|
|
|
windowRect.GetComponent<CanvasGroup>().alpha = track.timeDurationSubmodule.CheckTimeInDuration(songTime) ? 1f : 0.2f;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
void TransformChanged()
|
|
|
|
|
|
{
|
|
|
|
|
|
RectTransform canvasRect = EditorManager.instance.inspectorCanvas.GetComponent<RectTransform>();
|
|
|
|
|
|
Vector2 ScreenPosition = EditorManager.instance.cameraManager.currentCamera.WorldToScreenPoint(trackHead.transform.position);
|
2025-05-01 22:54:56 +08:00
|
|
|
|
|
2025-05-02 22:34:42 +08:00
|
|
|
|
if (RectTransformUtility.ScreenPointToLocalPointInRectangle(canvasRect, ScreenPosition, null, out Vector2 uiPosition))
|
|
|
|
|
|
{
|
|
|
|
|
|
windowRect.anchoredPosition = new Vector2(uiPosition.x, uiPosition.y + 150f);
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
public void ChangeFocus()
|
|
|
|
|
|
{
|
|
|
|
|
|
isFocus = !isFocus;
|
2025-05-02 22:34:42 +08:00
|
|
|
|
if (trackPositioner != null) trackPositioner.enabled = isFocus;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
public void ChangeXdevide(string devide)
|
|
|
|
|
|
{
|
|
|
|
|
|
Xdevide = int.Parse(devide);
|
2025-05-02 22:34:42 +08:00
|
|
|
|
SpawnBeatline();
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
public void ChangeBeatdevide(string devide)
|
|
|
|
|
|
{
|
|
|
|
|
|
beatDeviver = int.Parse(devide);
|
|
|
|
|
|
SpawnBeatline();
|
|
|
|
|
|
OnceSpawnNote();
|
|
|
|
|
|
}
|
|
|
|
|
|
public void ChangeExpand()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (isExpand)
|
|
|
|
|
|
{
|
|
|
|
|
|
isExpand = false;
|
2025-05-02 22:34:42 +08:00
|
|
|
|
windowRect.sizeDelta = new Vector2(100, windowRect.sizeDelta.y);
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
isExpand = true;
|
|
|
|
|
|
windowRect.sizeDelta = new Vector2(500, windowRect.sizeDelta.y);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2025-07-17 16:44:38 +08:00
|
|
|
|
public void ChangeXWidth(string change)
|
|
|
|
|
|
{
|
|
|
|
|
|
XWidth = int.Parse(change);
|
|
|
|
|
|
OnceSpawnNote();
|
|
|
|
|
|
}
|
2025-05-11 00:20:27 +08:00
|
|
|
|
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)
|
2025-05-01 22:54:56 +08:00
|
|
|
|
{
|
2025-07-17 16:44:38 +08:00
|
|
|
|
if (!EditorManager.instance.useNotePrefab)
|
|
|
|
|
|
{
|
|
|
|
|
|
LogWindow.Log("Please enable \"Note Prefab\" in EditorManager", Color.red);
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2025-05-01 22:54:56 +08:00
|
|
|
|
// 获取鼠标在 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;
|
2025-08-10 16:00:46 +08:00
|
|
|
|
float time = Mathf.Round(far * timePerBeat * 1000f) / 1000f;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
|
2025-07-18 18:43:09 +08:00
|
|
|
|
|
2025-07-17 16:44:38 +08:00
|
|
|
|
switch (NoteCode)
|
2025-05-01 22:54:56 +08:00
|
|
|
|
{
|
2025-07-17 16:44:38 +08:00
|
|
|
|
case 0:
|
|
|
|
|
|
Tap a = Tap.GenerateElement("New Tap", Guid.NewGuid(), new List<string>(), true, gameElement, time);
|
|
|
|
|
|
noteBases.Add(a);
|
2025-07-18 18:43:09 +08:00
|
|
|
|
a.noteVisual.transformSubmodule.originalPosition = new Vector3(isExpand ? (localMousePosition.x / XWidth) : 0f, 0f, 0f);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
a.noteVisual.transformSubmodule.Refresh();
|
|
|
|
|
|
SpawnNote(a, isExpand ? localMousePosition.x : 0f);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 3:
|
|
|
|
|
|
Hold b = Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), true, gameElement, time, time + 0.5f);
|
|
|
|
|
|
noteBases.Add(b);
|
2025-07-18 18:43:09 +08:00
|
|
|
|
b.noteVisual.transformSubmodule.originalPosition = new Vector3(isExpand ? (localMousePosition.x / XWidth) : 0f, 0f, 0f);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
b.noteVisual.transformSubmodule.Refresh();
|
|
|
|
|
|
SpawnNote(b, isExpand ? localMousePosition.x : 0f);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 1:
|
|
|
|
|
|
Stay c = Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), true, gameElement, time);
|
|
|
|
|
|
noteBases.Add(c);
|
2025-07-18 18:43:09 +08:00
|
|
|
|
c.noteVisual.transformSubmodule.originalPosition = new Vector3(isExpand ? (localMousePosition.x / XWidth) : 0f, 0f, 0f);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
c.noteVisual.transformSubmodule.Refresh();
|
|
|
|
|
|
SpawnNote(c, isExpand ? localMousePosition.x : 0f);
|
|
|
|
|
|
break;
|
|
|
|
|
|
case 2:
|
|
|
|
|
|
Flick d = Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), true, gameElement, time, new List<Vector2>());
|
|
|
|
|
|
noteBases.Add(d);
|
2025-07-18 18:43:09 +08:00
|
|
|
|
d.noteVisual.transformSubmodule.originalPosition = new Vector3(isExpand ? (localMousePosition.x / XWidth) : 0f, 0f, 0f);
|
2025-07-17 16:44:38 +08:00
|
|
|
|
d.noteVisual.transformSubmodule.Refresh();
|
|
|
|
|
|
SpawnNote(d, isExpand ? localMousePosition.x : 0f);
|
|
|
|
|
|
break;
|
|
|
|
|
|
default:
|
|
|
|
|
|
break;
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
2025-07-17 16:44:38 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-05-01 22:54:56 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|