repaired the motherfucking hold note problem which troubled us longer than 2 months
added some UI
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using Unity.VisualScripting;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using TMPro;
|
||||
|
||||
public class NoteSpawner : MonoBehaviour
|
||||
@@ -18,19 +20,11 @@ public class NoteSpawner : MonoBehaviour
|
||||
public float spawnOffset = 0f; // 生成音符时的时间偏移量
|
||||
public float bpm;
|
||||
|
||||
private HoldNote _holdNoteComponentCache; // 缓存HoldNote组件
|
||||
private Beatmap beatmap;
|
||||
private float startTime; // 存储歌曲开始时间
|
||||
private bool isSpawning = false;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
// 初始化HoldNote组件缓存
|
||||
if (holdNoteStartPrefabs != null && holdNoteStartPrefabs.Length > 0)
|
||||
{
|
||||
_holdNoteComponentCache = holdNoteStartPrefabs[0].GetComponent<HoldNote>();
|
||||
}
|
||||
}
|
||||
private static int holdNoteIdCounter = 0; // 全局唯一长音符 ID 计数器
|
||||
|
||||
public void LoadBeatmap(Beatmap loadedBeatmap)
|
||||
{
|
||||
@@ -40,13 +34,13 @@ public class NoteSpawner : MonoBehaviour
|
||||
beatmap = loadedBeatmap;
|
||||
if (beatmap == null)
|
||||
{
|
||||
//Debug.LogError("加载的谱面为空!");
|
||||
Debug.LogError("加载的谱面为空!");
|
||||
return;
|
||||
}
|
||||
|
||||
bpm = beatmap.bpm;
|
||||
startTime = Time.time;
|
||||
//Debug.Log($"歌曲开始时间: {startTime}");
|
||||
Debug.Log($"歌曲开始时间: {startTime}");
|
||||
StartCoroutine(SpawnNotes());
|
||||
}
|
||||
|
||||
@@ -54,7 +48,7 @@ public class NoteSpawner : MonoBehaviour
|
||||
{
|
||||
if (beatmap == null || beatmap.notes == null)
|
||||
{
|
||||
//Debug.LogError("谱面数据为空!");
|
||||
Debug.LogError("谱面数据为空!");
|
||||
isSpawning = false;
|
||||
yield break;
|
||||
}
|
||||
@@ -87,23 +81,23 @@ public class NoteSpawner : MonoBehaviour
|
||||
{
|
||||
if (noteData.trackIndex < 0 || noteData.trackIndex >= spawnPoints.Length)
|
||||
{
|
||||
//Debug.LogError("轨道索引超出范围!");
|
||||
Debug.LogError("轨道索引超出范围!");
|
||||
return;
|
||||
}
|
||||
|
||||
KeyCode key = KeyBindingManager.GetKeyForColor(noteData.color);
|
||||
if (key == KeyCode.None)
|
||||
{
|
||||
//Debug.LogError($"未找到颜色 {noteData.color} 对应的按键!请检查 KeyBindingManager 是否正确初始化。");
|
||||
Debug.LogError($"未找到颜色 {noteData.color} 对应的按键!请检查 KeyBindingManager 是否正确初始化。");
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log($"生成短音符:颜色={noteData.color}, 按键={key}, 轨道={noteData.trackIndex}");
|
||||
Debug.Log($"生成短音符:颜色={noteData.color}, 按键={key}, 轨道={noteData.trackIndex}");
|
||||
|
||||
GameObject note = notePool.GetNote(noteData.color);
|
||||
if (note == null)
|
||||
{
|
||||
//Debug.LogError("对象池返回了一个空音符!");
|
||||
Debug.LogError("对象池返回了一个空音符!");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -115,61 +109,66 @@ public class NoteSpawner : MonoBehaviour
|
||||
{
|
||||
float noteSpawnTime = Time.time;
|
||||
noteScript.Setup(key, noteData.trackIndex, CalculateSpeed(), noteData.time, noteData.color);
|
||||
//Debug.Log($"到达时间:{noteSpawnTime + (60f / bpm) * 4}");
|
||||
Debug.Log($"到达时间:{noteSpawnTime + (60f / bpm) * 4}");
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.LogError("音符预制体缺少 Note 组件!");
|
||||
Debug.LogError("音符预制体缺少 Note 组件!");
|
||||
}
|
||||
}
|
||||
|
||||
public void SpawnHoldNote(NoteData noteData)
|
||||
{
|
||||
if (noteData == null)
|
||||
{
|
||||
//Debug.LogError("NoteData为空!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (noteData.trackIndex < 0 || noteData.trackIndex >= spawnPoints.Length)
|
||||
{
|
||||
//Debug.LogError("轨道索引超出范围!");
|
||||
Debug.LogError("轨道索引超出范围!");
|
||||
return;
|
||||
}
|
||||
|
||||
KeyCode key = KeyBindingManager.GetKeyForColor(noteData.color);
|
||||
if (key == KeyCode.None)
|
||||
{
|
||||
//Debug.LogError($"未找到颜色 {noteData.color} 对应的按键!");
|
||||
Debug.LogError($"未找到颜色 {noteData.color} 对应的按键!");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(noteData.color))
|
||||
{
|
||||
//Debug.LogError("[NoteSpawner] noteData.color 为空,无法生成音符!");
|
||||
Debug.LogError("[NoteSpawner] noteData.color 为空,无法生成音符!");
|
||||
return;
|
||||
}
|
||||
|
||||
//Debug.Log($"生成时间:{Time.time}");
|
||||
//Debug.Log($"生成长音符:颜色={noteData.color}, 按键={key}, 轨道={noteData.trackIndex}");
|
||||
Debug.Log($"生成时间:{Time.time}");
|
||||
Debug.Log($"生成长音符:颜色={noteData.color}, 按键={key}, 轨道={noteData.trackIndex}");
|
||||
|
||||
float segmentInterval = (60f / bpm) / 4f;
|
||||
int segmentCount = Mathf.CeilToInt(noteData.length / segmentInterval);
|
||||
Transform spawnPoint = spawnPoints[noteData.trackIndex];
|
||||
float scheduledEndTime = noteData.time + noteData.length;
|
||||
|
||||
// 生成唯一ID
|
||||
int holdNoteId = GenerateHoldNoteId();
|
||||
// 生成唯一 id
|
||||
int holdNoteId = Random.Range(100000, 999999);
|
||||
|
||||
// 生成 Start 段
|
||||
GameObject startObj = notePool.GetStartNote(noteData.color);
|
||||
if (startObj == null)
|
||||
{
|
||||
//Debug.LogError("对象池返回空 hold note start!");
|
||||
Debug.LogError("对象池返回空 hold note start!");
|
||||
return;
|
||||
}
|
||||
startObj.transform.position = spawnPoint.position;
|
||||
startObj.transform.rotation = Quaternion.identity;
|
||||
|
||||
SetupHoldNoteSegment(startObj, spawnPoint, holdNoteId, noteData, key, 0f, false, "start", scheduledEndTime);
|
||||
HoldNote holdNote = startObj.GetComponent<HoldNote>();
|
||||
if (holdNote != null)
|
||||
{
|
||||
holdNote.Setup(holdNoteId, noteData.trackIndex, CalculateSpeed(), noteData.time, 0f, false, scheduledEndTime, noteData.color, key, "start");
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("长音符 start 部分缺少 HoldNote 组件!");
|
||||
return;
|
||||
}
|
||||
|
||||
// 生成 Middle 和 End 段
|
||||
for (int i = 1; i < segmentCount; i++)
|
||||
@@ -178,9 +177,6 @@ public class NoteSpawner : MonoBehaviour
|
||||
bool isEndSegment = (i == segmentCount - 1);
|
||||
string partType = isEndSegment ? "end" : "middle";
|
||||
|
||||
// 应用gracePeriod
|
||||
segmentDelay = CalculateSegmentDelay(segmentDelay, isEndSegment);
|
||||
|
||||
GameObject segObj = notePool.GetHoldNoteSegment(noteData.color);
|
||||
if (segObj == null)
|
||||
{
|
||||
@@ -188,60 +184,34 @@ public class NoteSpawner : MonoBehaviour
|
||||
continue;
|
||||
}
|
||||
|
||||
SetupHoldNoteSegment(segObj, spawnPoint, holdNoteId, noteData, key, segmentDelay, isEndSegment, partType, scheduledEndTime);
|
||||
}
|
||||
}
|
||||
segObj.transform.position = spawnPoint.position;
|
||||
segObj.transform.rotation = Quaternion.identity;
|
||||
|
||||
private int GenerateHoldNoteId()
|
||||
{
|
||||
return System.Guid.NewGuid().GetHashCode() & 0x7FFFFFFF; // 确保生成正数ID
|
||||
}
|
||||
|
||||
private float CalculateSegmentDelay(float delay, bool isEndSegment)
|
||||
{
|
||||
if (!isEndSegment && _holdNoteComponentCache != null)
|
||||
{
|
||||
delay -= _holdNoteComponentCache.segmentGracePeriod;
|
||||
return Mathf.Max(delay, 0);
|
||||
}
|
||||
return delay;
|
||||
}
|
||||
|
||||
private void SetupHoldNoteSegment(GameObject noteObj, Transform spawnPoint, int holdNoteId,
|
||||
NoteData noteData, KeyCode key, float delay,
|
||||
bool isEnd, string type, float scheduledEndTime)
|
||||
{
|
||||
noteObj.transform.position = spawnPoint.position;
|
||||
noteObj.transform.rotation = Quaternion.identity;
|
||||
|
||||
HoldNote holdNote = noteObj.GetComponent<HoldNote>();
|
||||
if (holdNote != null)
|
||||
{
|
||||
holdNote.Setup(holdNoteId, noteData.trackIndex, CalculateSpeed(),
|
||||
noteData.time, delay, isEnd, scheduledEndTime,
|
||||
noteData.color, key, type);
|
||||
|
||||
// 注册结束时间
|
||||
if (isEnd)
|
||||
HoldNote holdSeg = segObj.GetComponent<HoldNote>();
|
||||
if (holdSeg != null)
|
||||
{
|
||||
JudgeManager.Instance.RegisterScheduledEndTime(holdNoteId.ToString(), scheduledEndTime);
|
||||
holdSeg.Setup(holdNoteId, noteData.trackIndex, CalculateSpeed(), noteData.time, segmentDelay, isEndSegment, scheduledEndTime, noteData.color, key, partType);
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.LogError("长音符片段缺少 HoldNote 组件!");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//Debug.LogError("长音符片段缺少 HoldNote 组件!");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private float CalculateSpeed()
|
||||
{
|
||||
float noteTravelTime = (60f / bpm) * 4;
|
||||
return 10.75f / noteTravelTime;
|
||||
}
|
||||
|
||||
public void ResetAllHoldNotes()
|
||||
private void Update()
|
||||
{
|
||||
JudgeManager.Instance.ResetAllHoldNotes();
|
||||
//Debug.Log("重置所有长音符状态");
|
||||
//if (globalGameTime.text=="0.01")
|
||||
//{
|
||||
// bgMusicAudioSource.Play();
|
||||
//}
|
||||
//else return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user