260 lines
8.3 KiB
C#
260 lines
8.3 KiB
C#
using System.Collections;
|
||
using System.Collections.Generic;
|
||
using System.Data;
|
||
using System.Linq;
|
||
using Ichni;
|
||
using Ichni.Editor;
|
||
using Ichni.RhythmGame;
|
||
using Unity.VisualScripting;
|
||
using UnityEngine;
|
||
using UnityEngine.InputSystem;
|
||
using UnityEngine.UI;
|
||
|
||
public class FlexibleFloatTab : MonoBehaviour
|
||
{
|
||
public GraphicalFlexibleFloatWindow FatherWindow;
|
||
public List<EventPoint> eventPoints;
|
||
public RectTransform Area;
|
||
public RectTransform BeatArea;
|
||
public RectTransform XBeatArea;
|
||
public EventPoint eventPoint;
|
||
public GameObject BeatLine;
|
||
public Button TabButton;
|
||
public string Title;
|
||
public FlexibleFloat connectFloat;
|
||
public int BeatDeviver => FatherWindow.BeatDeviver;
|
||
public int BeatNextDeviver => FatherWindow.BeatNextDeviver;
|
||
public bool linked = false;//TODOTODO!
|
||
|
||
// 初始化函数
|
||
public void Initialize(FlexibleFloat flexibleFloat, string title)
|
||
{
|
||
Title = title;
|
||
ClearChildren(Area);
|
||
ClearChildren(BeatArea);
|
||
eventPoints = new List<EventPoint>();
|
||
connectFloat = flexibleFloat;
|
||
CreateBeatLines();
|
||
CreateEventPoints();
|
||
Area.localPosition = new Vector3(FatherWindow.songBeat * BeatDeviver, 0, 0);
|
||
}
|
||
|
||
// 清除子节点
|
||
private void ClearChildren(RectTransform parent)
|
||
{
|
||
for (int i = 0; i < parent.childCount; i++)
|
||
{
|
||
Destroy(parent.GetChild(i).gameObject);
|
||
}
|
||
}
|
||
|
||
// 创建节拍线
|
||
private void CreateBeatLines()
|
||
{
|
||
// 先清空BeatArea下的所有子对象,防止重复生成
|
||
for (int i = BeatArea.childCount - 1; i >= 0; i--)
|
||
{
|
||
Destroy(BeatArea.GetChild(i).gameObject);
|
||
}
|
||
float maxX = 1400f + (3 * BeatDeviver);
|
||
int totalBeats = (int)(EditorManager.instance.songInformation.song.length / FatherWindow.timePerBeat);
|
||
for (int i = 0; i < totalBeats; i++)
|
||
{
|
||
float posX = BeatDeviver * i;
|
||
if (posX > maxX)
|
||
{
|
||
break;
|
||
}
|
||
GameObject u = Instantiate(BeatLine, BeatArea);
|
||
u.transform.localPosition = new Vector3(posX, 0, 0);
|
||
}
|
||
}
|
||
|
||
// 创建事件点
|
||
private void CreateEventPoints()
|
||
{
|
||
for (int i = 0; i <= connectFloat.animations.Count - 1; i++)
|
||
{
|
||
AnimatedFloat animatedFloat = connectFloat.animations[i];
|
||
EventPoint eventPoint = Instantiate(this.eventPoint, Area);
|
||
eventPoint.FatherTab = this;
|
||
eventPoint.Initialize(animatedFloat);
|
||
eventPoints.Add(eventPoint);
|
||
LinkEventPoints(i, eventPoint);
|
||
}
|
||
foreach (var i in eventPoints)
|
||
{
|
||
i.ReDraw(scalevalue);
|
||
}
|
||
}
|
||
|
||
// 更新函数
|
||
public void Update()
|
||
{
|
||
bool isOnEv = false;
|
||
foreach (var i in eventPoints)
|
||
{
|
||
isOnEv = RectTransformUtility.RectangleContainsScreenPoint(i.selectButton.GetComponent<RectTransform>(), Mouse.current.position.ReadValue());
|
||
if (isOnEv) break;
|
||
}
|
||
Vector3 newPosition = new Vector3(-FatherWindow.songBeat * BeatDeviver, 0, 0);
|
||
Area.localPosition = newPosition;
|
||
BeatArea.localPosition = newPosition;
|
||
while (true)
|
||
{
|
||
BeatArea.localPosition += new Vector3(BeatDeviver, 0, 0);
|
||
if (BeatArea.localPosition.x > ((-200f) - BeatDeviver))
|
||
{
|
||
break;
|
||
}
|
||
}
|
||
XBeatArea.localPosition = BeatArea.localPosition;
|
||
if (RectTransformUtility.RectangleContainsScreenPoint(TabButton.GetComponent<RectTransform>(), Mouse.current.position.ReadValue()))
|
||
if (!isOnEv && Mouse.current.leftButton.wasPressedThisFrame)
|
||
{
|
||
AddEvent();
|
||
}
|
||
}
|
||
|
||
// 添加事件
|
||
public void AddEvent()
|
||
{
|
||
|
||
if (Keyboard.current.ctrlKey.isPressed)
|
||
{
|
||
EventPoint eventPoint = Instantiate(this.eventPoint, Area);
|
||
eventPoint.FatherTab = this;
|
||
eventPoint.Initialize(new AnimatedFloat(GetBeat(),
|
||
GetBeat() + (float.Parse(FatherWindow.EventMultiplier.text) * FatherWindow.timePerBeat), 0, 0, AnimationCurveType.Linear));
|
||
eventPoints.Insert(FindInsertIndex(eventPoint.animatedFloat.startTime), eventPoint);
|
||
LinkNewEventPoint(eventPoint, linked);
|
||
eventPoint.ReDraw(scalevalue);
|
||
eventPoint.selectButton.onClick.Invoke();
|
||
FatherWindow.ChangeValue();
|
||
connectFloat.Add(eventPoint.animatedFloat);
|
||
connectFloat.Sort();
|
||
}
|
||
// else
|
||
// {
|
||
// if (FatherWindow.ConnectedPoint != null) FatherWindow.ConnectedPoint.UpLoad();
|
||
// }
|
||
}
|
||
public void SpawnEvent(AnimatedFloat animatedFloat)
|
||
{
|
||
EventPoint eventPoint = Instantiate(this.eventPoint, Area);
|
||
eventPoint.FatherTab = this;
|
||
eventPoint.Initialize(animatedFloat);
|
||
eventPoints.Insert(FindInsertIndex(eventPoint.animatedFloat.startTime), eventPoint);
|
||
LinkNewEventPoint(eventPoint);
|
||
eventPoint.ReDraw(scalevalue);
|
||
connectFloat.Add(eventPoint.animatedFloat);
|
||
connectFloat.Sort();
|
||
}
|
||
|
||
// 添加调用 EventPoint 类的接口
|
||
public void LinkEventPoints(int index, EventPoint eventPoint)
|
||
{
|
||
eventPoint.LinkEventPoints(eventPoints, index);
|
||
}
|
||
|
||
|
||
|
||
public void LinkNewEventPoint(EventPoint eventPoint, bool link = false)
|
||
{
|
||
eventPoint.LinkNewEventPoint(eventPoints, link, scalevalue);
|
||
}
|
||
|
||
public int FindInsertIndex(float startTime)
|
||
{
|
||
return EventPoint.FindInsertIndex(eventPoints, startTime);
|
||
}
|
||
|
||
// 获取节拍
|
||
public float GetBeat()
|
||
{
|
||
// 获取鼠标在 BeatArea 中的相对位置
|
||
Vector2 localMousePosition = Area.InverseTransformPoint(Mouse.current.position.ReadValue());
|
||
//Debug.Log(localMousePosition);
|
||
|
||
float mouseBeat = localMousePosition.x / BeatDeviver;
|
||
float far = 0f;
|
||
while (far < mouseBeat)
|
||
{
|
||
far += 1f / BeatNextDeviver;
|
||
}
|
||
far -= 1f / BeatNextDeviver;
|
||
return far * FatherWindow.timePerBeat;
|
||
}
|
||
|
||
public float scalevalue => FatherWindow.scalevalue;
|
||
|
||
// 曲线缩放
|
||
public void CurveScale(float value)
|
||
{
|
||
foreach (EventPoint i in eventPoints)
|
||
{
|
||
i.ReDraw(value);
|
||
}
|
||
}
|
||
|
||
// 改变X轴节拍
|
||
public void XbeatCnange(int num)
|
||
{
|
||
ClearChildren(XBeatArea);
|
||
for (int i = 1; i < num; i++)
|
||
{
|
||
foreach (Transform child in BeatArea)
|
||
{
|
||
GameObject newChild = Instantiate(child.gameObject, XBeatArea);
|
||
CanvasGroup canvasGroup = newChild.GetComponent<CanvasGroup>();
|
||
newChild.transform.localPosition = new Vector3(child.localPosition.x + ((float)BeatDeviver) / num * i, child.localPosition.y, child.localPosition.z);
|
||
if (canvasGroup == null)
|
||
{
|
||
canvasGroup = newChild.AddComponent<CanvasGroup>();
|
||
}
|
||
canvasGroup.alpha = 0.1f;
|
||
}
|
||
}
|
||
}
|
||
|
||
// 移除动画
|
||
public void remoceAnim(AnimatedFloat a)
|
||
{
|
||
if (connectFloat.animations.Contains(a))
|
||
{
|
||
connectFloat.animations.Remove(a);
|
||
}
|
||
}
|
||
|
||
/// <summary>
|
||
/// 从事件点列表中移除指定的事件点,并更新其前后连接关系。
|
||
/// </summary>
|
||
/// <param name="eventPoint">要移除的事件点。</param>
|
||
public void RemoveEventPoint(EventPoint eventPoint)
|
||
{
|
||
if (eventPoints.Contains(eventPoint))
|
||
{
|
||
// 更新前后事件点的连接关系
|
||
if (eventPoint.LastEventPoint != null)
|
||
{
|
||
eventPoint.LastEventPoint.NextEventPoint = eventPoint.NextEventPoint;
|
||
eventPoint.LastEventPoint.ReDraw(scalevalue);
|
||
}
|
||
if (eventPoint.NextEventPoint != null)
|
||
{
|
||
eventPoint.NextEventPoint.LastEventPoint = eventPoint.LastEventPoint;
|
||
eventPoint.NextEventPoint.ReDraw(scalevalue);
|
||
}
|
||
|
||
// 从列表中移除事件点
|
||
eventPoints.Remove(eventPoint);
|
||
|
||
// 从连接的动画中移除
|
||
connectFloat.animations.Remove(eventPoint.animatedFloat);
|
||
|
||
// 销毁事件点对象
|
||
Destroy(eventPoint.gameObject);
|
||
}
|
||
}
|
||
}
|