好多新内容
This commit is contained in:
@@ -216,6 +216,9 @@ public class HoldNote : BaseNote
|
||||
if (controller != null)
|
||||
{
|
||||
controller.OnJudgeZoneChanged += OnJudgeZoneChanged;
|
||||
// 去物理判定:进入/离开判定区的分段逻辑由 controller 几何驱动回调触发(替代自身 OnTrigger)。
|
||||
controller.OnZoneEnterGeometry += HandleZoneEnter;
|
||||
controller.OnZoneExitGeometry += HandleZoneExit;
|
||||
}
|
||||
|
||||
cachedJudgeManager = JudgeManager.Instance;
|
||||
@@ -322,6 +325,8 @@ public class HoldNote : BaseNote
|
||||
if (controller != null)
|
||||
{
|
||||
controller.OnJudgeZoneChanged -= OnJudgeZoneChanged;
|
||||
controller.OnZoneEnterGeometry -= HandleZoneEnter;
|
||||
controller.OnZoneExitGeometry -= HandleZoneExit;
|
||||
}
|
||||
|
||||
if (JudgeManager.Instance != null)
|
||||
@@ -342,13 +347,53 @@ public class HoldNote : BaseNote
|
||||
|
||||
private void PlayHitAnimation()
|
||||
{
|
||||
var controller = AnimationController.Global ?? anim;
|
||||
var controller = GetAnimationController();
|
||||
if (controller != null)
|
||||
{
|
||||
controller.PlayDestroyAnimation(noteColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void PlayMiddleSegmentHitFx()
|
||||
{
|
||||
PlayHitAnimation();
|
||||
TrackJudgeHitEffectController.PlayTrackHitFx(trackIndex);
|
||||
}
|
||||
|
||||
private void EnsureHoldParticleLoop()
|
||||
{
|
||||
if (!isHoldActive || string.IsNullOrEmpty(noteColor))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// 按长音符 id 记账,避免同轨道旧段回收误停当前长按特效。
|
||||
GetAnimationController()?.StartHoldParticles(noteColor, id);
|
||||
}
|
||||
|
||||
private AnimationController GetAnimationController()
|
||||
{
|
||||
if (AnimationController.Global != null)
|
||||
return AnimationController.Global;
|
||||
|
||||
if (anim == null)
|
||||
{
|
||||
anim = SceneObjectLookupCache.FindAny<AnimationController>();
|
||||
}
|
||||
|
||||
return anim;
|
||||
}
|
||||
|
||||
private void StartHoldFxLoop()
|
||||
{
|
||||
GetAnimationController()?.StartHoldParticles(noteColor, id);
|
||||
}
|
||||
|
||||
private void StopHoldFxLoop()
|
||||
{
|
||||
GetAnimationController()?.StopHoldParticles(id);
|
||||
}
|
||||
|
||||
private IEnumerator DelayedDisableAnimation(GameObject animationObject, float delay)
|
||||
{
|
||||
// No-op: we used to disable the shared AnimationController here which stopped coroutines.
|
||||
@@ -481,24 +526,43 @@ public class HoldNote : BaseNote
|
||||
if (!isHoldActive && jm != null && jm.IsStartJudged(noteID) && !jm.HasNoteReleased(noteID) && keyHeld)
|
||||
{
|
||||
isHoldActive = true;
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
StartHoldFxLoop();
|
||||
if (debugEnabled) Debug.Log($"[HoldNote] Start particles started for {noteID} color={noteColor} at time={now:F3}");
|
||||
}
|
||||
|
||||
if (isHoldActive && jm != null && jm.IsStartJudged(noteID) && !jm.HasNoteReleased(noteID) && keyHeld)
|
||||
{
|
||||
EnsureHoldParticleLoop();
|
||||
}
|
||||
|
||||
// Auto-miss checks when inside judge line
|
||||
if (hasEnteredLine)
|
||||
{
|
||||
float missRangeScaled = (judgeConfig?.missRange ?? 0.5f) * holdWindowMultiplier;
|
||||
// 只对"尚未判定"的 start 段做超时 auto-Miss。已成功判定的 start 段(玩家已按下、
|
||||
// 正持续按住)绝不能在此被误判 Miss——否则 EvaluateHoldEnd(forceMiss) 会调 StopHoldParticles,
|
||||
// 把长按持续特效杀掉。物理版时 collider 早已离开判定区不会走到这里;几何版 exit 更晚才暴露此隐患。
|
||||
bool startAlreadyJudged = jm != null && jm.IsStartJudged(noteID);
|
||||
if (segment == NoteSegment.Start && now > hitTime + missRangeScaled)
|
||||
{
|
||||
if (debugEnabled) Debug.Log($"[HoldNote] START auto-Miss: {noteColor}");
|
||||
|
||||
// Register miss properly via EvaluateHoldEnd
|
||||
EvaluateHoldEnd(now, true);
|
||||
|
||||
isJudged = true;
|
||||
ScheduleReturnToPool(0.2f);
|
||||
return;
|
||||
if (!startAlreadyJudged)
|
||||
{
|
||||
if (debugEnabled) Debug.Log($"[HoldNote] START auto-Miss: {noteColor}");
|
||||
// 未判定的 start 超时 → 正常 Miss。
|
||||
EvaluateHoldEnd(now, true);
|
||||
isJudged = true;
|
||||
ScheduleReturnToPool(0.2f);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 已成功判定的 start 段:其视觉/判定使命已完成(end 段负责收尾),
|
||||
// 静默回收即可,绝不能走 EvaluateHoldEnd(会 StopHoldParticles 杀掉长按持续特效)。
|
||||
// isHoldActive 由 middle/end 段各自维持,不受本段回收影响。
|
||||
isJudged = true;
|
||||
ScheduleReturnToPool(0.2f);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
else if (segment == NoteSegment.End && now > scheduledEndTime + missRangeScaled)
|
||||
@@ -515,7 +579,7 @@ public class HoldNote : BaseNote
|
||||
if (isHoldActive && keyUp)
|
||||
{
|
||||
isHoldActive = false;
|
||||
AnimationController.Global?.StopHoldParticles();
|
||||
StopHoldFxLoop();
|
||||
if (debugEnabled) Debug.Log($"[HoldNote] KeyUp {keyToPress} detected. NoteID: {noteID}, Segment: {segment}, Type: {type}");
|
||||
|
||||
if (!hasReleased)
|
||||
@@ -571,15 +635,18 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
else if (segment == NoteSegment.Middle
|
||||
&& jm != null && jm.IsStartJudged(noteID)
|
||||
&& isHoldActive
|
||||
&& keyHeld
|
||||
&& !jm.HasNoteReleased(noteID))
|
||||
{
|
||||
isHoldActive = true;
|
||||
EnsureHoldParticleLoop();
|
||||
if (now >= hitTime)
|
||||
{
|
||||
if (hasEnteredLine)
|
||||
{
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote] Middle passed: {noteColor}");
|
||||
PlayHitAnimation();
|
||||
// 按住阶段粒子由 AnimationController 的固定 tick 统一生成。
|
||||
// 中段经过只负责保持循环,不额外加打一组,避免长音符前半段因中段密集而粒子频率过高。
|
||||
jm?.RegisterMiddlePassed(noteID);
|
||||
ScheduleReturnToPool(0.2f);
|
||||
isJudged = true;
|
||||
@@ -610,6 +677,11 @@ public class HoldNote : BaseNote
|
||||
isHoldActive = true;
|
||||
}
|
||||
|
||||
if (isHoldActive && jm != null && jm.IsStartJudged(noteID) && !jm.HasNoteReleased(noteID))
|
||||
{
|
||||
EnsureHoldParticleLoop();
|
||||
}
|
||||
|
||||
if (segment == NoteSegment.Start)
|
||||
{
|
||||
bool startResolved = jm != null && jm.IsStartJudged(noteID);
|
||||
@@ -642,7 +714,7 @@ public class HoldNote : BaseNote
|
||||
if (now >= hitTime && hasEnteredLine)
|
||||
{
|
||||
if (debugEnabled) Debug.Log($"[HoldNote.AutoPlay] Middle passed: {noteColor}");
|
||||
PlayHitAnimation();
|
||||
// 按住阶段粒子由 AnimationController 的固定 tick 统一生成。
|
||||
jm?.RegisterMiddlePassed(noteID);
|
||||
ScheduleReturnToPool(0.2f);
|
||||
isJudged = true;
|
||||
@@ -690,7 +762,7 @@ public class HoldNote : BaseNote
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, true);
|
||||
isHoldActive = true;
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
StartHoldFxLoop();
|
||||
|
||||
holdStartTime = pressTime;
|
||||
HoldNoteJudgePool.RegisterStart(noteID, pressTime, hitTime, scheduledEndTime, noteColor, trackIndex, (object)noteData);
|
||||
@@ -707,10 +779,9 @@ public class HoldNote : BaseNote
|
||||
globalNoteEffect.TryTrigger(noteData != null ? noteData.noteFunction : null);
|
||||
}
|
||||
|
||||
private void OnTriggerEnter2D(Collider2D collision)
|
||||
// 去物理判定:原 OnTriggerEnter2D 的分段逻辑,改由 controller 几何驱动调用,逻辑完全一致。
|
||||
private void HandleZoneEnter()
|
||||
{
|
||||
if (!collision.CompareTag("JudgmentLine")) return;
|
||||
|
||||
hasEnteredLine = true;
|
||||
|
||||
if (segment == NoteSegment.Start)
|
||||
@@ -753,7 +824,7 @@ public class HoldNote : BaseNote
|
||||
isJudged = true;
|
||||
// Terminate input - mark key as released
|
||||
isHoldActive = false;
|
||||
AnimationController.Global?.StopHoldParticles();
|
||||
StopHoldFxLoop();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -761,10 +832,9 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
}
|
||||
|
||||
private void OnTriggerExit2D(Collider2D collision)
|
||||
// 去物理判定:原 OnTriggerExit2D 的分段逻辑,改由 controller 几何驱动调用,逻辑完全一致。
|
||||
private void HandleZoneExit()
|
||||
{
|
||||
if (!collision.CompareTag("JudgmentLine")) return;
|
||||
|
||||
if (segment == NoteSegment.Start)
|
||||
{
|
||||
UnregisterQueueIfNeeded();
|
||||
@@ -922,7 +992,7 @@ public class HoldNote : BaseNote
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, true);
|
||||
isHoldActive = true;
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
StartHoldFxLoop();
|
||||
|
||||
// record when the hold started so we can compute held fraction later
|
||||
holdStartTime = pressTime;
|
||||
@@ -938,7 +1008,7 @@ public class HoldNote : BaseNote
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, true);
|
||||
isHoldActive = true;
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
StartHoldFxLoop();
|
||||
|
||||
holdStartTime = pressTime;
|
||||
|
||||
@@ -952,7 +1022,7 @@ public class HoldNote : BaseNote
|
||||
JudgeManager.Instance.RegisterStartJudged(noteID, true);
|
||||
isHoldActive = true;
|
||||
PlayHitAnimation();
|
||||
AnimationController.Global?.StartHoldParticles(noteColor);
|
||||
StartHoldFxLoop();
|
||||
|
||||
holdStartTime = pressTime;
|
||||
|
||||
@@ -1260,7 +1330,21 @@ public class HoldNote : BaseNote
|
||||
if (JudgeManager.IsDebugEnabled) Debug.Log($"[HoldNote] Hold end NotifyNoteHit called: TrackIndex={TrackIndex} trackIndexField={trackIndex} result={result} triggeredHold={triggeredHold} triggeredTap={triggeredTap}");
|
||||
}
|
||||
|
||||
AnimationController.Global?.StopHoldParticles();
|
||||
// 只有命中(非 Miss)才播放打击特效;Miss 不该触发击打效果。
|
||||
// 与上面 1253-1256 的 TrackJudgeHitEffectController 守卫保持一致。
|
||||
if (result != "Miss")
|
||||
{
|
||||
PlayHitAnimation();
|
||||
}
|
||||
|
||||
// 关键修复(长条结束仍按住→持续特效不停):hold 已完整结算,标记该 note 为"已释放/已完结"。
|
||||
// 否则玩家继续按住时,其它仍存活的段 Update 满足 (isHoldActive && IsStartJudged && !HasNoteReleased
|
||||
// && keyHeld) 会再次 EnsureHoldParticleLoop 重启持续 tick——即使 hold 逻辑上已经结束。
|
||||
// 置 released 后,所有段的 Update 门槛 !HasNoteReleased 不再成立,持续循环不会被重启。
|
||||
hasReleased = true;
|
||||
JudgeManager.Instance?.RegisterNoteReleased(noteID, true);
|
||||
|
||||
StopHoldFxLoop();
|
||||
|
||||
// Release the track lock immediately after end evaluation so the next hold can start on time
|
||||
ReleaseTrackJudgeLockSafe();
|
||||
@@ -1390,10 +1474,18 @@ public class HoldNote : BaseNote
|
||||
hitTime = 0f;
|
||||
scheduledEndTime = 0f;
|
||||
hasEnteredLine = false;
|
||||
// 普通 start/middle 段回收时,同一条长音符可能仍在持续按住,不能在这里停掉持续特效。
|
||||
// 真正停止由 keyUp / end 判定路径负责;这里只兜底处理 end 段池化泄漏。
|
||||
if (isHoldActive && segment == NoteSegment.End)
|
||||
{
|
||||
StopHoldFxLoop();
|
||||
}
|
||||
isJudged = false;
|
||||
isHoldActive = false;
|
||||
hasBeenHeldFromStart = false;
|
||||
prevTrackHeld = false;
|
||||
// 去物理判定:池化复用时重置 controller 的几何判定状态(重新算阈值、清进入标志)。
|
||||
if (controller != null) controller.ResetJudgeZoneGeometry();
|
||||
|
||||
holdStartTime = -1f;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user