250 lines
8.7 KiB
C#
250 lines
8.7 KiB
C#
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<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;
|
||
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<SplinePositioner>();
|
||
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<RawImage>();
|
||
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<NotefabContoler>().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<CanvasGroup>().alpha = (songTime >= trackTimeSubmoduleMovable.trackStartTime && songTime <= trackTimeSubmoduleMovable.trackEndTime) ? 1f : 0.2f;
|
||
|
||
}
|
||
else if (track.trackTimeSubmodule is TrackTimeSubmoduleStatic)
|
||
{
|
||
trackPositioner.SetPercent(0f);
|
||
}
|
||
TransformChanged();
|
||
windowRect.GetComponent<CanvasGroup>().alpha = track.timeDurationSubmodule.CheckTimeInDuration(songTime) ? 1f : 0.2f;
|
||
}
|
||
if (selectedGameObject.GetType() != typeof(TMP_InputField) && RectTransformUtility.RectangleContainsScreenPoint(windowRect, Mouse.current.position.ReadValue()))
|
||
{
|
||
DetectNote();
|
||
|
||
}
|
||
|
||
}
|
||
void TransformChanged()
|
||
{
|
||
RectTransform canvasRect = EditorManager.instance.inspectorCanvas.GetComponent<RectTransform>();
|
||
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<string>(), false, gameElement, time);
|
||
noteBases.Add(a);
|
||
SpawnNote(a);
|
||
break;
|
||
case 3:
|
||
Hold b = Hold.GenerateElement("New Hold", Guid.NewGuid(), new List<string>(), false, gameElement, time, time + 0.5f);
|
||
noteBases.Add(b);
|
||
SpawnNote(b);
|
||
break;
|
||
case 1:
|
||
Stay c = Stay.GenerateElement("New Stay", Guid.NewGuid(), new List<string>(), false, gameElement, time);
|
||
noteBases.Add(c);
|
||
SpawnNote(c);
|
||
break;
|
||
case 2:
|
||
Flick d = Flick.GenerateElement("New Flick", Guid.NewGuid(), new List<string>(), false, gameElement, time, new List<Vector2>());
|
||
noteBases.Add(d);
|
||
SpawnNote(d);
|
||
break;
|
||
}
|
||
|
||
}
|
||
}
|
||
}
|