备份,准备做双端
This commit is contained in:
@@ -203,9 +203,9 @@ public class Note : BaseNote
|
||||
this.judgeConfig = judgeConfig;
|
||||
this.noteData = data;
|
||||
this.isSyncNote = isSync;
|
||||
|
||||
|
||||
// Set miss deadline: hitTime + missRange (the latest time to judge before auto-miss)
|
||||
float missRange = (judgeConfig?.missRange ?? 0.5f);
|
||||
float missRange = judgeConfig != null ? judgeConfig.missRange : 0.2f;
|
||||
this.missDeadlineTime = hitTime + missRange;
|
||||
|
||||
if (controller != null)
|
||||
@@ -213,7 +213,7 @@ public class Note : BaseNote
|
||||
controller.SetSpeed(speed);
|
||||
}
|
||||
|
||||
InputManager.OnKeyPressed += HandlePress;
|
||||
InputManager.OnTrackPressedWithDspTime += HandlePress;
|
||||
|
||||
if (judgeConfig == null)
|
||||
{
|
||||
@@ -221,13 +221,13 @@ public class Note : BaseNote
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"NoteJudgeConfig: perfect={judgeConfig.perfectRange}, great={judgeConfig.greatRange}, good={judgeConfig.goodRange}, miss={judgeConfig.missRange}");
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"NoteJudgeConfig: perfectE={judgeConfig.perfectEarlyRange} perfectL={judgeConfig.perfectLateRange}, greatE={judgeConfig.greatEarlyRange} greatL={judgeConfig.greatLateRange}, goodE={judgeConfig.goodEarlyRange} goodL={judgeConfig.goodLateRange}, miss={judgeConfig.missRange}");
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
InputManager.OnKeyPressed -= HandlePress;
|
||||
InputManager.OnTrackPressedWithDspTime -= HandlePress;
|
||||
// Release lock if we still hold it
|
||||
if (hasLock)
|
||||
{
|
||||
@@ -238,11 +238,15 @@ public class Note : BaseNote
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// 【性能】NowSongTime 每次访问都读 native AudioSettings.dspTime;帧内其值恒定,
|
||||
// 缓存到局部只读一次,与原先多次读取同值,行为等效。
|
||||
float now = GameplayClock.NowSongTime;
|
||||
|
||||
// Autoplay: automatically judge notes as Perfect without user input.
|
||||
if (!isJudged && GameConfig.autoPlayEnabled && gameObject.activeSelf)
|
||||
{
|
||||
// Only judge once the note reaches its scheduled hit time.
|
||||
if (GameplayClock.NowSongTime >= hitTime)
|
||||
if (now >= hitTime)
|
||||
{
|
||||
TryAutoJudgePerfect();
|
||||
}
|
||||
@@ -252,9 +256,9 @@ public class Note : BaseNote
|
||||
// Force miss if we've passed the deadline without being judged
|
||||
if (!isJudged && gameObject.activeSelf)
|
||||
{
|
||||
if (GameplayClock.NowSongTime >= missDeadlineTime)
|
||||
if (now >= missDeadlineTime)
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[Note.Update] Forcing miss for {noteColor} on track {TrackIndex}: now={GameplayClock.NowSongTime:F3}, deadline={missDeadlineTime:F3}");
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[Note.Update] Forcing miss for {noteColor} on track {TrackIndex}: now={now:F3}, deadline={missDeadlineTime:F3}");
|
||||
JudgeMiss();
|
||||
}
|
||||
}
|
||||
@@ -278,7 +282,9 @@ public class Note : BaseNote
|
||||
hasLock = locked;
|
||||
|
||||
float pressTime = hitTime; // force Perfect regardless of frame timing
|
||||
float maxWindow = (judgeConfig?.missRange ?? 0.5f);
|
||||
float maxWindow = judgeConfig != null
|
||||
? Mathf.Max(judgeConfig.goodEarlyRange, judgeConfig.goodLateRange)
|
||||
: 0.5f;
|
||||
|
||||
// If not in judge zone, still allow judgement (we're using scheduled timing).
|
||||
if (TrackKeyManager.Instance != null)
|
||||
@@ -344,14 +350,14 @@ public class Note : BaseNote
|
||||
Judge();
|
||||
}
|
||||
|
||||
private void HandlePress(KeyCode key)
|
||||
private void HandlePress(int trackIndex, double pressDspTime)
|
||||
{
|
||||
// Autoplay ignores player input to guarantee Perfect.
|
||||
if (GameConfig.autoPlayEnabled)
|
||||
return;
|
||||
|
||||
// only proceed for matching key and not already judged
|
||||
if (isJudged || key != keyToPress)
|
||||
// only proceed for matching track and not already judged
|
||||
if (isJudged || trackIndex != TrackIndex)
|
||||
return;
|
||||
|
||||
string myId = CachedId;
|
||||
@@ -362,8 +368,12 @@ public class Note : BaseNote
|
||||
|
||||
hasLock = true;
|
||||
|
||||
float pressTime = GameplayClock.NowSongTime;
|
||||
float maxWindow = (judgeConfig?.missRange ?? 0.5f);
|
||||
// Convert the Input System press timestamp (dspTime) into song time for sub-frame-accurate
|
||||
// judgement. Equivalent to the old NowSongTime read but captured at the exact input moment.
|
||||
float pressTime = GameplayClock.SongTimeFromDsp(pressDspTime);
|
||||
float maxWindow = judgeConfig != null
|
||||
? Mathf.Max(judgeConfig.goodEarlyRange, judgeConfig.goodLateRange)
|
||||
: 0.5f;
|
||||
|
||||
// If there is a controller and the note is not inside judge zone, only allow judgment
|
||||
// if the press time is within the allowed window. Otherwise ignore the press.
|
||||
@@ -399,14 +409,19 @@ public class Note : BaseNote
|
||||
}
|
||||
}
|
||||
|
||||
float timeDifference = Mathf.Abs(pressTime - hitTime);
|
||||
// raw offset ms: positive = note was early (hitTime > pressTime)
|
||||
float rawOffsetMs = (hitTime - pressTime) * 1000f;
|
||||
float offset = pressTime - hitTime; // positive = late, negative = early
|
||||
string judgeResult = null;
|
||||
|
||||
if (judgeConfig != null)
|
||||
{
|
||||
if (timeDifference <= judgeConfig.perfectRange)
|
||||
float earlyTolerance, lateTolerance;
|
||||
|
||||
// Perfect window
|
||||
earlyTolerance = judgeConfig.perfectEarlyRange;
|
||||
lateTolerance = judgeConfig.perfectLateRange;
|
||||
if (offset >= -earlyTolerance && offset <= lateTolerance)
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"{keyToPress}: Perfect");
|
||||
judgeResult = "Perfect";
|
||||
@@ -415,7 +430,8 @@ public class Note : BaseNote
|
||||
if (noteData != null) noteData.judgeOffsetMs = rawOffsetMs;
|
||||
ScoreManager.Instance.RecordOffset(rawOffsetMs);
|
||||
}
|
||||
else if (timeDifference <= judgeConfig.greatRange)
|
||||
// Great window
|
||||
else if (offset >= -(earlyTolerance = judgeConfig.greatEarlyRange) && offset <= (lateTolerance = judgeConfig.greatLateRange))
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"{keyToPress}: Great");
|
||||
judgeResult = "Great";
|
||||
@@ -424,7 +440,8 @@ public class Note : BaseNote
|
||||
if (noteData != null) noteData.judgeOffsetMs = rawOffsetMs;
|
||||
ScoreManager.Instance.RecordOffset(rawOffsetMs);
|
||||
}
|
||||
else if (timeDifference <= judgeConfig.goodRange)
|
||||
// Good window
|
||||
else if (offset >= -(earlyTolerance = judgeConfig.goodEarlyRange) && offset <= (lateTolerance = judgeConfig.goodLateRange))
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"{keyToPress}: Good");
|
||||
judgeResult = "Good";
|
||||
@@ -451,21 +468,22 @@ public class Note : BaseNote
|
||||
}
|
||||
else
|
||||
{
|
||||
// fallback timing
|
||||
// fallback timing (symmetric, legacy)
|
||||
float timeDifference = Mathf.Abs(pressTime - hitTime);
|
||||
if (timeDifference <= 0.08f)
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"{keyToPress}: Perfect");
|
||||
judgeResult = "Perfect";
|
||||
ScoreManager.Instance.countPerfect += 1;
|
||||
// Add missing offset record for fallback path too if possible
|
||||
ScoreManager.Instance.RecordOffset(0);
|
||||
ScoreManager.Instance.RecordOffset(rawOffsetMs);
|
||||
}
|
||||
else if (timeDifference <= 0.15f)
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"{keyToPress}: Great");
|
||||
judgeResult = "Great";
|
||||
ScoreManager.Instance.countGreat += 1;
|
||||
ScoreManager.Instance.RecordOffset(0);
|
||||
ScoreManager.Instance.RecordOffset(rawOffsetMs);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -522,6 +540,10 @@ public class Note : BaseNote
|
||||
LogTapJudge(judgeResult, rawOffsetMs, rewrittenToPerfect, false, pressTime);
|
||||
GameplayLevelRuleEventBus.NotifyTapJudged(TrackIndex, judgeResult, pressTime, noteData);
|
||||
|
||||
// FAST/SLOW 预埋反馈:offset = pressTime - hitTime,正=晚(SLOW)/负=早(FAST)。
|
||||
// 默认无订阅者时为 no-op,不影响任何判定/计分逻辑。
|
||||
JudgeFeedback.Report(TrackIndex, judgeResult, offset * 1000f);
|
||||
|
||||
if (isSyncNote && judgeResult != "Miss")
|
||||
{
|
||||
effectEventController.TryTriggerMultiNoteShake();
|
||||
@@ -656,8 +678,8 @@ public class Note : BaseNote
|
||||
|
||||
private void ReturnToPool()
|
||||
{
|
||||
InputManager.OnKeyPressed -= HandlePress;
|
||||
|
||||
InputManager.OnTrackPressedWithDspTime -= HandlePress;
|
||||
|
||||
// CRITICAL: Always release lock and unregister before deactivating
|
||||
string myId = CachedId;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user