Files
ichni_Creator_Studio/Assets/Scripts/DynamicUI/Timeline/TimePointerModule.cs
TRAfoer 7048bd21e6 看完了
顺手加了个element改名同步hierarchy
3D遮挡!!!
然后发现当track或者folder旋转时pathnode的法线(旋转)不会跟着
以上测试放在IceFlowerMaster项目中
还有 现在没中文字体
2025-03-15 18:33:16 +08:00

247 lines
8.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using System;
using System.Collections;
using System.Collections.Generic;
using Ichni.RhythmGame;
using UniRx;
using UnityEngine;
using UnityEngine.Serialization;
namespace Ichni.Editor
{
public partial class TimePointerModule : MonoBehaviour
{
private Timeline timeline => EditorManager.instance.uiManager.timeline;
private SongInformation songInformation => EditorManager.instance.songInformation;
public GameObject timePointerPrefab;
public List<TimePointer> timePointerList;
public RectTransform timePointerArea;
public RectTransform visibleTimePointerArea;
public RectTransform moveTabPoint;//用于显示timeline上的tab
public RectTransform mainTimePointer;
public float intervalUnit;
public float timePointerInterval;
public float sizeNegative, sizePositive;
public int negativePointerAmount; // 负方向指示线的数量
public int positivePointerAmount, totalPointerAmount;
/// <summary>
/// delay时间区间中(-delay, 0)的距离偏移量
/// </summary>
public float delayDistanceOffset;
public float leftSideSongTime, rightSideSongTime, songTimeDistance;
private void Start()
{
Observable.NextFrame().Subscribe(_ =>
{
timePointerList = new List<TimePointer>();
Initialize(songInformation.delay, songInformation.bpm);
});
}
private void Update()
{
if (EditorManager.instance.musicPlayer.isPlaying)
{
SetRange(songInformation.songTime);
}
timePointerList.ForEach(pointer =>
{
bool isActive = pointer.time >= leftSideSongTime && pointer.time <= rightSideSongTime;
pointer.gameObject.SetActive(isActive);
});
if (OnePointer != null) moveTabPoint.localPosition = new Vector3(timePointerArea.localPosition.x + OnePointer.transform.localPosition.x - timePointerInterval, -45f, 0);
foreach (var i in moveTabPoint.transform.GetComponentsInChildren<SubTab>())
{
if (i.Time >= songInformation.songTime)
{
i.transform.localScale = new Vector3(1, 1, 1);
}
else
{
i.transform.localScale = new Vector3(0, 0, 0);
}
}
}
/// <summary>
/// 初始化所有Timeline指示线
/// </summary>
/// <param name="delay"></param>
/// <param name="bpm"></param>
public void Initialize(float delay, float bpm)
{
timePointerInterval = 30;
ClearPointers();
int beatDivider = 1;
intervalUnit = (60f / bpm) / beatDivider * 1000;
sizeNegative = delay * beatDivider / timeline.timePerBeat;
// 计算负方向指示线的数量
negativePointerAmount = Mathf.CeilToInt(sizeNegative);
sizePositive = songInformation.song.length * beatDivider / timeline.timePerBeat;
positivePointerAmount = Mathf.CeilToInt(sizePositive);
totalPointerAmount = negativePointerAmount + positivePointerAmount;
timePointerArea.sizeDelta = new Vector2(timePointerInterval * (sizeNegative + sizePositive), 60f);
delayDistanceOffset = timePointerInterval * (negativePointerAmount - sizeNegative);
leftSideSongTime = timeline.beatmapStartTime;
rightSideSongTime = timeline.timePerBeat * (visibleTimePointerArea.rect.width / timePointerInterval);
songTimeDistance = rightSideSongTime;
for (int i = -negativePointerAmount; i <= positivePointerAmount; i++)
{
CreatePointer(beatDivider, i);
}
//ChangeSongTimeDistance(0);
SetRange(timeline.beatmapStartTime);
}
}
public partial class TimePointerModule
{
/// <summary>
/// 设置Timeline的显示区间区间宽度使用当前的区间宽度
/// </summary>
/// <param name="startTime">开始时间,结束时间即(开始时间+区间宽度)</param>
public void SetRange(float startTime)
{
startTime = Mathf.Clamp(startTime, timeline.beatmapStartTime, songInformation.song.length);
timePointerArea.anchoredPosition =
new Vector2((timePointerArea.sizeDelta.x / 2) -
(startTime + songInformation.delay) / timeline.timePerBeat * timePointerInterval, 0);
float proportion = mainTimePointer.anchoredPosition.x / visibleTimePointerArea.rect.width;
leftSideSongTime = startTime - songTimeDistance * proportion;
rightSideSongTime = startTime + songTimeDistance * (1 - proportion);
}
/// <summary>
/// 生成指示线
/// </summary>
/// <param name="beatDivider">细分X分音符</param>
/// <param name="index"></param>
TimePointer OnePointer = null;
private void CreatePointer(int beatDivider, int index)
{
TimePointer pointer = Instantiate(timePointerPrefab, timePointerArea).GetComponent<TimePointer>();
timePointerList.Add(pointer);
pointer.index = index;
pointer.GetComponent<RectTransform>().anchoredPosition =
new Vector2((index + negativePointerAmount) * timePointerInterval + 15f - delayDistanceOffset, 0);
pointer.time = index * intervalUnit / 1000f;
pointer.intervalUnitText.text = Mathf.RoundToInt(index * intervalUnit).ToString();
if (index == 0)
{
OnePointer = timePointerList[timePointerList.Count - 1];
}
if (beatDivider > 1)
{
}
}
/// <summary>
/// 更新指示线位置
/// </summary>
public void UpdatePointers()
{
// 计算延迟距离偏移量
delayDistanceOffset = timePointerInterval * (negativePointerAmount - sizeNegative);
// 更新指示线区域的大小
timePointerArea.sizeDelta = new Vector2(timePointerInterval * totalPointerAmount, 55f);
// 更新每个指示线的位置
foreach (var pointer in timePointerList)
{
pointer.GetComponent<RectTransform>().anchoredPosition =
new Vector2((pointer.index + negativePointerAmount) * timePointerInterval + 15f - delayDistanceOffset, 0);
}
}
/// <summary>
/// 清楚所有指示线
/// </summary>
private void ClearPointers()
{
foreach (var pointer in timePointerList)
{
Destroy(pointer.gameObject);
}
timePointerList.Clear();
}
/// <summary>
/// 缩放时间线的展示时间宽度
/// </summary>
/// <param name="value">增减值</param>
public void ChangeSongTimeDistance(float value)
{
float oldDistance = songTimeDistance;
float changedDistance = songTimeDistance + value;
float songLength = songInformation.song.length;
if (changedDistance < 1 || changedDistance > songLength)
{
return;
}
float finalDistance = 0, finalValue = 0;
float superfluousDistance = changedDistance - songLength;
if (superfluousDistance > 0)
{
finalDistance = songLength;
finalValue = value - superfluousDistance;
}
else
{
finalDistance = changedDistance;
finalValue = value;
}
songTimeDistance = finalDistance;
float proportion = mainTimePointer.anchoredPosition.x /
visibleTimePointerArea.rect.width;
leftSideSongTime -= finalValue * (proportion);
rightSideSongTime += finalValue * (1 - proportion);
if (leftSideSongTime < -songInformation.delay)
{
rightSideSongTime += Mathf.Abs(leftSideSongTime);
leftSideSongTime = -songInformation.delay;
}
else if (rightSideSongTime > songLength)
{
leftSideSongTime -= (rightSideSongTime - songLength);
rightSideSongTime = songLength;
}
timePointerInterval = timePointerInterval / finalDistance * oldDistance;
UpdatePointers();
//UpdateListItems();
SetRange(leftSideSongTime);
}
}
}