using Unity.VisualScripting; /// /// BPM组单元,用于储存对应时间组的物件速度变化,与乐曲相关 /// public class BPMGroup { /*关于时间组与BPM变换的机制 *BPM变换是一种用来完成适应中间有BPM变换的歌曲的一种机制 *其原理是通过控制当前BPM的基准BPM的比值,使得NoteSpeed得以变化 *当BPM变换到比原定的数值更大时,那么音符的速度将会更快 *当BPM变换到比原定的数值更小时,那么音符的速度将会更慢 * *但是将这种变换设置为全局的是不合适的,因此我们从数据上为Note划分组别 *使得每一个时间组都可以被单独控制 *我们将在控制器重创建一个列表,统一管理列表中的所有时间组单元 *在每一个物件被实例化时,它将被传递对应的时间组单元的引用 * *每一个时间组单元通过更新自身存储的NoteSpeed以达到控制Note的效果 *因为每一个被创建的物件实例都会不断的通过NoteSpeed更新自身位置 * *由于时间组条数通常在100这个数量级以内,选择字典结构去管理是相对合适的 */ /// /// 当前BPM组的NoteSpeed /// public float CurrentNoteSpeed { get { if (CurrentBPM == 0) return 0; //单位向量*基础速度*音符流速*BPM/基准BPM return _noteStream * CurrentBPM * _baseSpeed / _baseBPM; } } private float _noteStream; private float _baseSpeed; private float _baseBPM; /// /// 每拍的时间长度(秒) /// public float Beat { get { return CurrentBPM > 0 ? 60f / CurrentBPM : 0f; } } /// /// 音符相对当前BPM的抵达下落目标所需时间,单位:ms /// public float InitializeOffset { get { if (CurrentNoteSpeed == 0) return 0; //到达目标点的时间 return TrackLength / CurrentNoteSpeed; } } /// /// 轨道长度,该值应当添加至游戏主控变成玩家偏好设置 /// private float TrackLength; public float CurrentBPM { set; get; } public int GroupNum { get; } public BPMGroup(float currentBPM, int groupNum, float noteStream, float baseSpeed, float baseBPM, float trackLength) { CurrentBPM = currentBPM; GroupNum = groupNum; _noteStream = noteStream; _baseSpeed = baseSpeed; _baseBPM = baseBPM; TrackLength = trackLength; } public void UpdatePlayerSetting(float noteStream, float baseSpeed, float baseBPM, float trackLength) { _noteStream = noteStream; _baseSpeed = baseSpeed; _baseBPM = baseBPM; TrackLength = trackLength; } public override string ToString() { return $"BPMGroup [Group: {GroupNum}]\n" + $"BPM: {CurrentBPM}\n" + $"Beat: {Beat:F3}s\n" + $"NoteSpeed: {CurrentNoteSpeed:F2}\n" + $"Stream: {_noteStream}\n" + $"BaseSpeed: {_baseSpeed}\n" + $"BaseBPM: {_baseBPM}\n" + $"InitializeOffset:{InitializeOffset}\n"+ $"当前速度:{CurrentNoteSpeed}" ; } }