Files
ichni_Creator_Studio/Assets/Scripts/DynamicUI/Timeline/Timeline.cs
TRAfoer 1b5084626d TimeLine大改
Signed-off-by: TRAfoer <lhf190@outlook.com>
2025-07-18 18:43:09 +08:00

219 lines
8.1 KiB
C#

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using Ichni.RhythmGame;
using Sirenix.Utilities;
using TMPro;
using Unity.VisualScripting;
using UnityEngine;
using UnityEngine.InputSystem;
using UnityEngine.Serialization;
using UnityEngine.UI;
namespace Ichni.Editor
{
public partial class Timeline : StaticWindow
{
public float songTime => EditorManager.instance.songInformation.songTime;
public float songBeat => EditorManager.instance.songInformation.songBeat;
public float beatmapStartTime => -EditorManager.instance.songInformation.delay;
public float timePerBeat => 60f / EditorManager.instance.songInformation.bpm;
public GameObject timelineTabRect;
public TimePointerModule timePointerModule;
public MusicPlayModule musicPlayModule;
public TMP_InputField TimeField;
public TMP_InputField BeatField;
public RectTransform GetinputArea;
public void Update()
{
if (EditorManager.instance.musicPlayer.isPlaying) UpdateTime();
if (RectTransformUtility.RectangleContainsScreenPoint(GetinputArea, Mouse.current.position.ReadValue()))
{
DetectSetRange();
}
}
private void DetectSetRange()
{
if (Keyboard.current.spaceKey.wasPressedThisFrame)
{
EditorManager.instance.musicPlayer.PlayMusic();
}
if (Mouse.current.scroll.ReadValue().y != 0)
{
if (Keyboard.current.leftCtrlKey.isPressed || Keyboard.current.rightCtrlKey.isPressed)
{
float scrollValue = Mouse.current.scroll.ReadValue().y / 12;
if (timePointerModule.timePointerInterval + scrollValue >= 30)
{
timePointerModule.timePointerInterval += scrollValue;
timePointerModule.SortPos();
SetTimeLine(EditorManager.instance.uiManager.inspector.connectedGameElement);
}
}
else
{
if (Mouse.current.scroll.ReadValue().y >= 0)
{
SetTime((EditorManager.instance.songInformation.songTime + timePerBeat).ToString());
}
else
{
if (EditorManager.instance.songInformation.songTime - timePerBeat >= 0)
SetTime((EditorManager.instance.songInformation.songTime - timePerBeat).ToString());
else
SetTime("0");
}
UpdateTime();
}
}
}
private void UpdateTime()
{
TimeField.text = songTime.ToString("F2");
BeatField.text = songBeat.ToString("F2");
}
private Tweener _activeTweener; // 保存当前动画的引用
public void SetTime(string time)
{
EditorManager.instance.musicPlayer.PauseMusic();
float parsedTime = float.Parse(time);
float offsetedtime = Mathf.Clamp(parsedTime - EditorManager.instance.songInformation.offset, 0, EditorManager.instance.songInformation.songLength);
EditorManager.instance.musicPlayer.audioSource.time = offsetedtime;
if (_activeTweener != null && _activeTweener.IsActive())
{
_activeTweener.Complete();
}
// 使用 DOTween 来平滑过渡到新的时间
_activeTweener = DOTween.To(() => EditorManager.instance.songInformation.songTime, x => EditorManager.instance.songInformation.songTime = x, parsedTime, 0.2f)
.OnUpdate(UpdateTime);
// timePointerModule.UpdatePointers();
// timePointerModule.SetRange(songTime);
}
public void SetBeat(string beat)
{
EditorManager.instance.musicPlayer.PauseMusic();
float parsedTime = float.Parse(beat) * timePerBeat;
float offsetedtime = Mathf.Clamp(parsedTime - EditorManager.instance.songInformation.offset, 0, EditorManager.instance.songInformation.songLength);
EditorManager.instance.musicPlayer.audioSource.time = offsetedtime;
if (_activeTweener != null && _activeTweener.IsActive())
{
_activeTweener.Complete();
}
_activeTweener = DOTween.To(() => EditorManager.instance.songInformation.songTime, x => EditorManager.instance.songInformation.songTime = x, parsedTime, 0.2f)
.OnUpdate(UpdateTime);
// EditorManager.instance.musicPlayer.audioSource.time = Mathf.Clamp((float.Parse(beat) * timePerBeat) - EditorManager.instance.songInformation.offset, 0, EditorManager.instance.songInformation.songLength);
// EditorManager.instance.songInformation.songTime = float.Parse(beat) * timePerBeat;
// timePointerModule.UpdatePointers();
// timePointerModule.SetRange(songTime);
}
}
public partial class Timeline
{
public TimelineTab timelineTabPrefab;
public Dictionary<Type, TimelineTab> timelineTabList = new Dictionary<Type, TimelineTab>();
private int TabIndex = 0;
public void SetTimeLine(GameElement element)//暂时好了(别的类型什么的传时间就好了)
{
TabIndex = 0;
for (int i = timePointerModule.moveTabPoint.childCount - 1; i >= 0; i--)
{
var transform = timePointerModule.moveTabPoint.transform.GetChild(i);
Destroy(transform.gameObject);
}
for (int i = timelineTabList.Count - 1; i >= 0; i--)
{
Destroy(timelineTabList.ElementAt(i).Value.gameObject);
timelineTabList.Remove(timelineTabList.ElementAt(i).Key);
}
Elementfind(element);
}
public RectTransform moveTabPoint;
public void Elementfind(GameElement element)
{
if (element == null) return;
foreach (var i in element.childElementList)
{
if (i is NoteBase)
{
if (!timelineTabList.ContainsKey(i.GetType()))
{
Add(i);
}
else
{
timelineTabList[i.GetType()].AddElement(i);
}
}
}
if (element is NoteBase)
{
if (!timelineTabList.ContainsKey(element.GetType()))
{
Add(element);
}
else
{
timelineTabList[element.GetType()].AddElement(element);
}
}
if (element is Track track)
{
var trackTimeSubmodule = track.submoduleList.FirstOrDefault(w => w is TrackTimeSubmodule) as TrackTimeSubmodule;
if (trackTimeSubmodule != null)
{
Add(trackTimeSubmodule);
}
}
var timeDurationSubmodule = element.submoduleList.FirstOrDefault(w => w is TimeDurationSubmodule) as TimeDurationSubmodule;
if (timeDurationSubmodule != null && timeDurationSubmodule.isOverridingDuration)
{
Add(timeDurationSubmodule);
}
}
private void Add(IBaseElement obj)
{
TimelineTab timelineTab = Instantiate(timelineTabPrefab, timelineTabRect.transform);
timelineTab.MoveArea = moveTabPoint;
timelineTab.TabIndex = TabIndex;
timelineTab.SetTab(obj, obj.GetType());
timelineTabList.Add(obj.GetType(), timelineTab);
TabIndex++;
}
}
}