展前冒死重构

This commit is contained in:
2026-07-24 04:43:13 +08:00
parent d09597472b
commit 4eb70b0ac9
61 changed files with 74951 additions and 328 deletions
+77 -11
View File
@@ -12,6 +12,23 @@ public class HoldNote : BaseNote
private string noteID = string.Empty;
private NoteSegment segment = NoteSegment.None;
// 获取用于生成判定 prefab 的颜色。如果 noteColor 为空(初始化异常),从 trackIndex 推导兜底。
private string GetColorForPrefab()
{
if (!string.IsNullOrEmpty(noteColor)) return noteColor;
if (trackIndex >= 0 && trackIndex < 5)
{
string[] trackColors = { "red", "green", "yellow", "purple", "blue" };
string fallback = trackColors[trackIndex];
if (JudgeManager.IsDebugEnabled) Debug.LogWarning($"[HoldNote] noteColor was null, using trackIndex {trackIndex} -> {fallback}");
return fallback;
}
Debug.LogError($"[HoldNote] Cannot derive color: noteColor is null and trackIndex {trackIndex} is invalid");
return null;
}
private float releaseTime = 0f;
private bool hasReleased = true;
private bool hasEnteredLine = false;
@@ -810,19 +827,20 @@ public class HoldNote : BaseNote
return;
}
// If the key is still being held down when end segment enters judge zone, immediately judge.
// Autoplay must ignore physical input to guarantee Perfect at scheduledEndTime.
if (!GameConfig.autoPlayEnabled && IsHeld() && JudgeManager.Instance.IsStartJudged(noteID) && !isJudged)
// END 段到达判定区时,如果头部已判定且玩家还没松手,立即自动结束(不等松手)。
// 让玩家"长按到尾部"即视为完成,无需精确松手时机——更符合直觉且降低难度。
// Autoplay 必须忽略物理输入,保证在 scheduledEndTime 精确判定 Perfect。
if (JudgeManager.Instance.IsStartJudged(noteID) && !JudgeManager.Instance.HasNoteReleased(noteID) && !isJudged)
{
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote] End entered while key still held: {noteColor}, forcing Perfect");
// Record release time as current time (player is still holding)
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote] End entered while note not yet released: {noteColor}, auto-finishing hold as Perfect");
// 记录松手时间为当前时刻(玩家按到尾部视为完美松手)
releaseTime = GameplayClock.NowSongTime;
hasReleased = true;
JudgeManager.Instance?.RegisterNoteReleased(noteID, true);
// Evaluate and judge the hold end - force Perfect since we reached the end while holding
// 判定并生成 prefab——force Perfect(按到尾部=完美完成)
EvaluateHoldEnd(releaseTime, false, true);
isJudged = true;
// Terminate input - mark key as released
// 终止输入:标记键已松开,停止持续特效
isHoldActive = false;
StopHoldFxLoop();
return;
@@ -1056,6 +1074,7 @@ public class HoldNote : BaseNote
if (result != "Miss")
{
TryRewriteNonMissJudgeToPerfect(trackIndex, ref result);
GameplayLevelRuleEventBus.NotifyHoldStarted(trackIndex, result, pressTime, noteData);
}
// show judge result and update combo/UI like short notes
@@ -1079,10 +1098,30 @@ public class HoldNote : BaseNote
TrackJudgeHitEffectController.PlayTrackHitFx(trackIndex);
}
// Do not spawn the judgement animation prefab for Start (head) presses to avoid duplicated prefabs
if (segment != NoteSegment.Start)
// Spawn judgement prefab:
// - START 段:只有 Miss 时才生成(点中的 Perfect/Good 不生成,避免头尾都弹;但 Miss 必须立即反馈)
// - END/BODY 段:总是生成(包括 Miss)
if (segment != NoteSegment.Start || result == "Miss")
{
Animation_GenerateJudgementSituationPrefab.Instance?.SpawnJudgePrefab(noteColor, result);
string colorForPrefab = GetColorForPrefab();
if (JudgeManager.IsDebugEnabled)
{
Debug.Log($"[HoldNote] Attempting to spawn prefab: segment={segment}, result={result}, noteColor={noteColor}, trackIndex={trackIndex}, derivedColor={colorForPrefab}, Instance={(Animation_GenerateJudgementSituationPrefab.Instance != null ? "EXISTS" : "NULL")}");
}
if (string.IsNullOrEmpty(colorForPrefab))
{
Debug.LogError($"[HoldNote] Cannot spawn prefab: colorForPrefab is null! noteColor={noteColor}, trackIndex={trackIndex}, segment={segment}, result={result}");
}
else if (Animation_GenerateJudgementSituationPrefab.Instance == null)
{
Debug.LogError($"[HoldNote] Cannot spawn prefab: Animation_GenerateJudgementSituationPrefab.Instance is NULL!");
}
else
{
Animation_GenerateJudgementSituationPrefab.Instance.SpawnJudgePrefab(colorForPrefab, result);
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote] SpawnJudgePrefab called successfully for {colorForPrefab}, {result}");
}
}
if (segment != NoteSegment.Start)
@@ -1239,6 +1278,15 @@ public class HoldNote : BaseNote
AdjustCountsAfterRewriteToPerfect(trackIndex, originalEndJudge);
}
if (result == "Miss")
{
GameplayLevelRuleEventBus.NotifyHoldBroken(trackIndex, result, actualReleaseTime, noteData);
}
else
{
GameplayLevelRuleEventBus.NotifyHoldCompleted(trackIndex, result, actualReleaseTime, noteData);
}
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote] END result for {noteID}: {result} (color={noteColor})");
// show UI/audio
@@ -1257,7 +1305,25 @@ public class HoldNote : BaseNote
}
// Ensure END always spawns judgement prefab (including Miss)
Animation_GenerateJudgementSituationPrefab.Instance?.SpawnJudgePrefab(noteColor, result);
string colorForPrefab = GetColorForPrefab();
if (JudgeManager.IsDebugEnabled)
{
Debug.Log($"[HoldNote.EvaluateHoldEnd] Attempting to spawn END prefab: result={result}, noteColor={noteColor}, trackIndex={trackIndex}, derivedColor={colorForPrefab}, Instance={(Animation_GenerateJudgementSituationPrefab.Instance != null ? "EXISTS" : "NULL")}");
}
if (string.IsNullOrEmpty(colorForPrefab))
{
Debug.LogError($"[HoldNote.EvaluateHoldEnd] Cannot spawn END prefab: colorForPrefab is null! noteColor={noteColor}, trackIndex={trackIndex}, result={result}");
}
else if (Animation_GenerateJudgementSituationPrefab.Instance == null)
{
Debug.LogError($"[HoldNote.EvaluateHoldEnd] Cannot spawn END prefab: Animation_GenerateJudgementSituationPrefab.Instance is NULL!");
}
else
{
Animation_GenerateJudgementSituationPrefab.Instance.SpawnJudgePrefab(colorForPrefab, result);
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote.EvaluateHoldEnd] SpawnJudgePrefab called successfully for {colorForPrefab}, {result}");
}
// --- Add scoring for End like short notes ---
try