add the connections and sendToTest.cs for connecting with the game test
This commit is contained in:
@@ -105,6 +105,7 @@ public class HoldNote : BaseNote
|
||||
this.noteID = id.ToString();
|
||||
this.keyToPress = key;
|
||||
this.noteColor = color;
|
||||
// hitTime now uses real time base passed in as 'time' plus delay
|
||||
this.hitTime = time + delay;
|
||||
this.segment = (delay == 0f) ? NoteSegment.Start :
|
||||
(isEnd ? NoteSegment.End : NoteSegment.Middle);
|
||||
@@ -117,6 +118,9 @@ public class HoldNote : BaseNote
|
||||
else
|
||||
Debug.Log($"HoldNoteJudgeConfig: perfect={judgeConfig.perfectRange}, great={judgeConfig.greatRange}, good={judgeConfig.goodRange}, miss={judgeConfig.missRange}");
|
||||
|
||||
// Debug info to help investigate end note visibility
|
||||
Debug.Log($"[HoldNote.Setup] id={noteID} segment={segment} type={type} hitTime={hitTime:F2} scheduledEnd={scheduledEndTime:F2} color={color} track={trackIndex}");
|
||||
|
||||
// 在 Setup 时注册初始状态
|
||||
JudgeManager.Instance?.RegisterNoteReleased(noteID, false);
|
||||
if (segment == NoteSegment.Start)
|
||||
@@ -134,82 +138,80 @@ public class HoldNote : BaseNote
|
||||
// 如果当前片段已经判定过,直接返回
|
||||
if (isJudged) return;
|
||||
|
||||
// 自动 Miss 判定:当音符经过判定线且未被判定时
|
||||
if (hasEnteredLine && !isJudged)
|
||||
{
|
||||
if (segment == NoteSegment.Start && Time.time > hitTime + judgeConfig?.missRange)
|
||||
{
|
||||
Debug.Log($"[HoldNote] START段超时自动Miss: {noteColor}");
|
||||
HandleStart();
|
||||
isJudged = true;
|
||||
}
|
||||
else if (segment == NoteSegment.End && Time.time > scheduledEndTime + (judgeConfig?.missRange ?? 0.3f))
|
||||
{
|
||||
Debug.Log($"[HoldNote] END段超时自动Miss: {noteColor}");
|
||||
HandleEnd(true);
|
||||
isJudged = true;
|
||||
}
|
||||
}
|
||||
|
||||
// **通用长按状态更新:**
|
||||
// 只有当isHoldActive为true时才检查松开操作,避免误判
|
||||
// 且仅在GetKeyUp时更新状态,避免重复操作
|
||||
if (isHoldActive && Input.GetKeyUp(keyToPress))
|
||||
{
|
||||
isHoldActive = false;
|
||||
Debug.Log($"[HoldNote] 按键 {keyToPress} 松开,长按状态失效。NoteID: {noteID}, Segment: {segment}, Type: {type}");
|
||||
// 如果是中间段或结束段,且因为松手导致长按失效,可以立即回收
|
||||
if (segment == NoteSegment.Middle || segment == NoteSegment.End)
|
||||
|
||||
// 当玩家松开按键时,向 JudgeManager 注册该长音符已被释放,确保尾部能正确检查释放状态
|
||||
if (!hasReleased)
|
||||
{
|
||||
// 注意:End段的判定在HandleEnd里,松手只是让isHoldActive为false,不代表End段判定已完成
|
||||
// 如果 End 段的判定窗口还没过,松手后 isHoldActive = false,End 段在 OnTriggerExit2D 才会回收
|
||||
// 或者在 HandleEnd 之前松手导致长按失效,HandleEnd 内部会判定 Miss
|
||||
hasReleased = true;
|
||||
releaseTime = Time.time;
|
||||
JudgeManager.Instance?.RegisterNoteReleased(noteID, true);
|
||||
Debug.Log($"[HoldNote] RegisterNoteReleased on KeyUp. NoteID: {noteID}, releaseTime={releaseTime:F2}");
|
||||
}
|
||||
}
|
||||
// 如果按键被按下,且Start段已经判定成功,则激活长按状态
|
||||
// 考虑到玩家可能在Start段通过后瞬间松手再按下,这里需要确保只要Start段判定成功且按键按住,isHoldActive就为true
|
||||
|
||||
if (JudgeManager.Instance.IsStartJudged(noteID) && Input.GetKey(keyToPress))
|
||||
{
|
||||
isHoldActive = true;
|
||||
}
|
||||
|
||||
|
||||
// Start段判定
|
||||
if (segment == NoteSegment.Start && hasEnteredLine)
|
||||
{
|
||||
// 在判定窗口内按下按键才触发判定
|
||||
if (Input.GetKeyDown(keyToPress))
|
||||
{
|
||||
HandleStart();
|
||||
isJudged = true; // 无论成功失败都标记为已判定,避免重复尝试
|
||||
}
|
||||
// 如果Start段进入判定区但玩家未按键,且已经错过最佳判定时机,可以考虑Miss并回收
|
||||
// 这部分逻辑现在放在 OnTriggerExit2D 里处理更合适
|
||||
}
|
||||
// Middle段判定:
|
||||
// 只有当头部已判定、且长按有效(按键持续按住),并且已经到达该Middle段的命中时间点时,才认为该Middle段通过。
|
||||
// Middle段本身没有独立的按键输入判定,它只是长按的延续。
|
||||
// Middle段判定:中段只负责视觉/回收,不做 End 判定统计
|
||||
else if (segment == NoteSegment.Middle
|
||||
&& JudgeManager.Instance.IsStartJudged(noteID) // 头部必须已判定
|
||||
&& isHoldActive // 必须处于长按有效状态(按键持续按住)
|
||||
&& !JudgeManager.Instance.HasNoteReleased(noteID)) // 确保End段还未被判定释放
|
||||
&& JudgeManager.Instance.IsStartJudged(noteID)
|
||||
&& isHoldActive
|
||||
&& !JudgeManager.Instance.HasNoteReleased(noteID))
|
||||
{
|
||||
// Debug.Log($"[HoldNote] Middle段状态检查: Time.time={Time.time:F2}, hitTime={hitTime:F2}, hasEnteredLine={hasEnteredLine}");
|
||||
if (Time.time >= hitTime)
|
||||
{
|
||||
// 确保它进入了判定线,但在Update中,即使没完全进入,只要时间到了且条件满足,也算通过
|
||||
// 但是,我们主要希望它在通过判定线后被回收
|
||||
// 因此,Middle段的回收逻辑更多依赖于DelayedAutoReturnCheck或OnTriggerExit2D
|
||||
if (hasEnteredLine) // 确保已经进入过判定线,防止音符提前消失
|
||||
if (hasEnteredLine)
|
||||
{
|
||||
Debug.Log($"[HoldNote] Middle段通过 (持续长按): {noteColor}");
|
||||
PlayHitAnimation();
|
||||
// 把通过事件上报给 JudgeManager(记录中段通过)
|
||||
JudgeManager.Instance?.RegisterMiddlePassed(noteID);
|
||||
ReturnToPool();
|
||||
isJudged = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
// End段判定
|
||||
// End段判定:现在 End 段判定由独立的尾部音符负责(即本对象仍可判定,但更重要的是尾部note会决定最终判定)
|
||||
else if (segment == NoteSegment.End
|
||||
&& JudgeManager.Instance.IsStartJudged(noteID) // 头部必须已判定
|
||||
&& !JudgeManager.Instance.HasNoteReleased(noteID)) // 确保还未被判定释放
|
||||
&& JudgeManager.Instance.IsStartJudged(noteID)
|
||||
&& !JudgeManager.Instance.HasNoteReleased(noteID))
|
||||
{
|
||||
// 只有当玩家松开按键时才触发End段判定
|
||||
if (Input.GetKeyUp(keyToPress))
|
||||
{
|
||||
HandleEnd();
|
||||
isJudged = true; // 标记为已判定
|
||||
}
|
||||
// 如果 End 段已经达到或超过了预定的释放时间 (scheduledEndTime),
|
||||
// 但玩家仍未松手,且长按状态仍然有效,这可能是玩家按得过长
|
||||
// 这种情况应该给予一个差的判定或者Miss
|
||||
else if (Time.time >= scheduledEndTime + 0.1f && isHoldActive) // 给予一点容错时间
|
||||
{
|
||||
Debug.Log($"[HoldNote] End段超时未松手,判定为Miss: {noteColor}");
|
||||
HandleEnd(true); // 传入true表示强制Miss
|
||||
isJudged = true;
|
||||
}
|
||||
}
|
||||
@@ -219,28 +221,31 @@ public class HoldNote : BaseNote
|
||||
{
|
||||
if (!collision.CompareTag("JudgmentLine")) return;
|
||||
|
||||
hasEnteredLine = true; // 只要进入判定线,就标记
|
||||
hasEnteredLine = true;
|
||||
|
||||
if (segment == NoteSegment.Middle)
|
||||
{
|
||||
// 进入判定区时记录是否已按住
|
||||
hasBeenHeldFromStart = Input.GetKey(keyToPress);
|
||||
Debug.Log($"[HoldNote] Middle段进入判定线: color={noteColor}, isStartJudged={JudgeManager.Instance.IsStartJudged(noteID)}, hasReleased={JudgeManager.Instance.HasNoteReleased(noteID)}, isKeyHeld={Input.GetKey(keyToPress)}, hasBeenHeldFromStart={hasBeenHeldFromStart}");
|
||||
|
||||
if (autoReturnCoroutine != null)
|
||||
StopCoroutine(autoReturnCoroutine);
|
||||
|
||||
// Middle段的延迟回收主要确保即使按住也能在适当时间回收
|
||||
// 重新思考这里的必要性,可能让Update和OnTriggerExit2D处理更直接
|
||||
// 暂时移除这里的 DelayedAutoReturnCheck,让 Update 和 OnTriggerExit2D 主导 Middle 段的生命周期
|
||||
// autoReturnCoroutine = StartCoroutine(DelayedAutoReturnCheck());
|
||||
}
|
||||
else if (segment == NoteSegment.End)
|
||||
{
|
||||
if (autoReturnCoroutine != null)
|
||||
StopCoroutine(autoReturnCoroutine);
|
||||
|
||||
// End段的延迟回收主要用于处理玩家是否松手,以及超时回收
|
||||
// 如果在尾部进入判定区时玩家已经释放按键,则此时应立即做 End 判定
|
||||
if (JudgeManager.Instance.HasNoteReleased(noteID) && !isJudged)
|
||||
{
|
||||
Debug.Log($"[HoldNote] End段进入判定线但已经释放,立即执行 End 判定: {noteColor}");
|
||||
HandleEnd();
|
||||
isJudged = true;
|
||||
// ReturnToPool handled inside HandleEnd
|
||||
return;
|
||||
}
|
||||
|
||||
autoReturnCoroutine = StartCoroutine(DelayedAutoReturnCheck());
|
||||
}
|
||||
}
|
||||
@@ -249,44 +254,60 @@ public class HoldNote : BaseNote
|
||||
{
|
||||
if (!collision.CompareTag("JudgmentLine")) return;
|
||||
|
||||
// Start段离开判定线时如果未被判定,则视为Miss并回收
|
||||
if (segment == NoteSegment.Start)
|
||||
{
|
||||
if (!JudgeManager.Instance.IsStartJudged(noteID))
|
||||
{
|
||||
Debug.Log($"[HoldNote] Start段离开判定线未判定,强制回收 (Miss): {noteColor}");
|
||||
// 可以触发一个Miss判定
|
||||
// JudgeManager.Instance.RecordMiss(noteID);
|
||||
Debug.Log($"[HoldNote] Start段离开判定线未判定,补偿 Miss 并回收: {noteColor}");
|
||||
// 确保未判定的 Start 段在离开判定线时登记为 Miss
|
||||
HandleStart();
|
||||
isJudged = true;
|
||||
ReturnToPool();
|
||||
}
|
||||
// 如果Start段已判定,那么它会通过DelayedReturn被回收,这里不做额外处理
|
||||
}
|
||||
// Middle段离开判定线时,如果头部未判定,或者长按已经失效(松手),则回收
|
||||
else if (segment == NoteSegment.Middle) // 这里修正了拼写错误
|
||||
else if (segment == NoteSegment.Middle)
|
||||
{
|
||||
// 无论Start段是否判定,如果Middle段离开了判定线,就应该回收
|
||||
// 因为它已经完成了它的“通过”或者“错过”的职责
|
||||
Debug.Log($"[HoldNote] Middle段离开判定线强制回收: {noteColor}");
|
||||
ReturnToPool();
|
||||
}
|
||||
// End段离开判定线时,如果头部未判定,或者长按已经失效,或者 End 段已经完成判定,则回收
|
||||
else if (segment == NoteSegment.End)
|
||||
{
|
||||
if (!isJudged) // 如果End段还没有被判定
|
||||
if (autoReturnCoroutine != null)
|
||||
{
|
||||
// 如果头部没判,或者长按中断,或者玩家按得过久(已经过了scheduledEndTime很多了)
|
||||
if (!JudgeManager.Instance.IsStartJudged(noteID) || !isHoldActive || Time.time > scheduledEndTime + 0.15f)
|
||||
StopCoroutine(autoReturnCoroutine);
|
||||
autoReturnCoroutine = null;
|
||||
}
|
||||
|
||||
// 在尾部离开判定线时,按如下规则处理:
|
||||
// - 如果头部未判定:补偿 Miss 并回收
|
||||
// - 如果头部已判定且玩家已经释放:执行 End 判定并回收
|
||||
// - 如果头部已判定且玩家仍在按住:不要强制 Miss,也不要立即回收,等待玩家松手或超时处理
|
||||
if (!isJudged)
|
||||
{
|
||||
if (!JudgeManager.Instance.IsStartJudged(noteID))
|
||||
{
|
||||
Debug.Log($"[HoldNote] End段离开判定线强制回收 (头部未判定或长按中断或超时): {noteColor}");
|
||||
// 可以在这里强制一个Miss判定,如果之前没触发过
|
||||
if (!JudgeManager.Instance.HasNoteReleased(noteID)) // 确保没有重复判定
|
||||
{
|
||||
HandleEnd(true); // 传入true表示强制Miss
|
||||
}
|
||||
Debug.Log($"[HoldNote] End段离开判定线且头部未判定,补偿 Miss: {noteColor}");
|
||||
if (!JudgeManager.Instance.HasNoteReleased(noteID))
|
||||
HandleEnd(true);
|
||||
ReturnToPool();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (JudgeManager.Instance.HasNoteReleased(noteID))
|
||||
{
|
||||
Debug.Log($"[HoldNote] End段离开判定线且已释放,执行 End 判定: {noteColor}");
|
||||
HandleEnd();
|
||||
isJudged = true;
|
||||
ReturnToPool();
|
||||
}
|
||||
else
|
||||
{
|
||||
// 头部已判定且玩家仍在按住:保持显示,不作回收或判定
|
||||
Debug.Log($"[HoldNote] End段离开判定线,头部已判定且仍在按住,保持显示等待松手或超时: {noteColor}");
|
||||
}
|
||||
}
|
||||
}
|
||||
else // 如果End段已经被判定过了,直接回收
|
||||
else
|
||||
{
|
||||
ReturnToPool();
|
||||
}
|
||||
@@ -295,33 +316,19 @@ public class HoldNote : BaseNote
|
||||
|
||||
private IEnumerator DelayedAutoReturnCheck()
|
||||
{
|
||||
// 这里的 DelayedAutoReturnCheck 主要是针对 End 段的超时未松手检查
|
||||
// 或者 Start 段的延迟补判(这部分已经移到 Update 和 HandleStart)
|
||||
yield return null;
|
||||
|
||||
if (segment == NoteSegment.End)
|
||||
{
|
||||
// 在这里等待,看玩家是否在 scheduledEndTime 之前松手
|
||||
// 如果到达 scheduledEndTime 玩家仍未松手,且长按有效,则继续等待
|
||||
// 如果玩家按得过长,可以在 Update 中触发 Miss 判定
|
||||
float timeToWait = Mathf.Max(0f, scheduledEndTime - Time.time);
|
||||
if (timeToWait > 0f)
|
||||
{
|
||||
yield return new WaitForSeconds(timeToWait);
|
||||
}
|
||||
|
||||
// 到达 scheduledEndTime 后再次检查
|
||||
// 如果此时玩家仍在按住,并且 Start 段已判定,但 End 段还没被判定释放
|
||||
// 说明玩家按得太久,判定为 Miss
|
||||
if (!isJudged && JudgeManager.Instance.IsStartJudged(noteID) && Input.GetKey(keyToPress))
|
||||
{
|
||||
Debug.Log($"[HoldNote] DelayedAutoReturnCheck (End段) 判定:玩家按得过长,Miss! {noteColor}");
|
||||
HandleEnd(true); // 强制 Miss
|
||||
}
|
||||
// 无论如何,如果 End 段已经过去了,但还没回收,就回收
|
||||
if (!gameObject.activeSelf)
|
||||
{
|
||||
yield break; // 修正!使用 yield break 来结束协程
|
||||
yield break;
|
||||
}
|
||||
ReturnToPool();
|
||||
}
|
||||
@@ -348,14 +355,13 @@ public class HoldNote : BaseNote
|
||||
isHoldActive = false; // Start Miss,长按状态不激活
|
||||
}
|
||||
InputManager.Instance?.ShowJudgeResult(trackIndex, result);
|
||||
// Start段判定后立即回收,因为它的视觉部分可能只需要短暂显示
|
||||
StartCoroutine(DelayedReturn());
|
||||
}
|
||||
|
||||
private IEnumerator DelayedReturn()
|
||||
{
|
||||
yield return new WaitForSeconds(0.05f); // 短暂延迟,确保视觉效果或数据更新
|
||||
if (gameObject.activeSelf) // 确保对象还活跃,防止重复回收
|
||||
yield return new WaitForSeconds(0.05f);
|
||||
if (gameObject.activeSelf)
|
||||
{
|
||||
ReturnToPool();
|
||||
}
|
||||
@@ -363,11 +369,28 @@ public class HoldNote : BaseNote
|
||||
|
||||
private void HandleEnd(bool forceMiss = false)
|
||||
{
|
||||
// 记录释放时间并在 JudgeManager 中登记已释放状态
|
||||
if (!hasReleased)
|
||||
{
|
||||
releaseTime = Time.time;
|
||||
hasReleased = true;
|
||||
JudgeManager.Instance?.RegisterNoteReleased(noteID, true);
|
||||
}
|
||||
|
||||
string result;
|
||||
|
||||
// 如果玩家在尾部进入判定区前就松手,则仅登记释放,不在此处进行最终判定和回收,除非是强制 Miss
|
||||
if (!hasEnteredLine && !forceMiss)
|
||||
{
|
||||
Debug.Log($"[HoldNote] HandleEnd: 提前松手,记录释放但等待尾部进入判定区再判定. NoteID={noteID}, color={noteColor}");
|
||||
return;
|
||||
}
|
||||
|
||||
// 现在进行正常判定逻辑
|
||||
releaseTime = Time.time;
|
||||
hasReleased = true;
|
||||
JudgeManager.Instance.RegisterNoteReleased(noteID, true);
|
||||
string result;
|
||||
// 只要头部判定通过,松手时机在判定区间内就给出对应判定
|
||||
|
||||
if (forceMiss || !JudgeManager.Instance.IsStartJudged(noteID))
|
||||
{
|
||||
result = "Miss";
|
||||
@@ -418,6 +441,7 @@ public class HoldNote : BaseNote
|
||||
}
|
||||
}
|
||||
InputManager.Instance?.ShowJudgeResult(trackIndex, result);
|
||||
teamUIController.Instance?.OnJudgeResult(result); // 新增:更新combo计数
|
||||
Debug.Log($"[HoldNote] END判定结果: {noteColor} {result} (release={releaseTime:F2}, target={scheduledEndTime:F2})");
|
||||
ReturnToPool();
|
||||
}
|
||||
@@ -430,27 +454,21 @@ public class HoldNote : BaseNote
|
||||
autoReturnCoroutine = null;
|
||||
}
|
||||
|
||||
// OnDisable时对End段的补偿处理:
|
||||
// 如果是End段,且尚未被判定,且Start段已判定,但此时按键已经松开 (通过 !Input.GetKey(keyToPress) 判断)
|
||||
// 这意味着玩家在离开判定区或因其他原因导致 OnDisable 时松手,但未触发正常的 HandleEnd
|
||||
if (segment == NoteSegment.End &&
|
||||
!isJudged && // 尚未判定
|
||||
JudgeManager.Instance.IsStartJudged(noteID)) // 头部已判定
|
||||
{
|
||||
// 如果按键已经松开,或者长按状态已经失效 (可能因为松开过快)
|
||||
if (!Input.GetKey(keyToPress) || !isHoldActive)
|
||||
// 只在头部已判定且玩家已松手时补偿 End 判定为 Miss;否则不要强制 Miss
|
||||
if (JudgeManager.Instance.HasNoteReleased(noteID) && !isHoldActive)
|
||||
{
|
||||
Debug.Log($"[HoldNote] OnDisable补偿End段Miss判定: {noteColor}");
|
||||
HandleEnd(true); // 强制Miss
|
||||
isJudged = true; // 标记已判定
|
||||
}
|
||||
else if (Input.GetKey(keyToPress))
|
||||
{
|
||||
// 如果End段离开了判定区,但是玩家还在按住,这属于按得过长
|
||||
Debug.Log($"[HoldNote] OnDisable:End段在离开判定区时玩家仍未松手,判定为Miss: {noteColor}");
|
||||
HandleEnd(true); // 强制Miss
|
||||
Debug.Log($"[HoldNote] OnDisable补偿End段判定(已释放): {noteColor}");
|
||||
HandleEnd(); // 正常判定(基于 releaseTime)
|
||||
isJudged = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log($"[HoldNote] OnDisable:End段未判定且尚有按键状态,跳过强制 Miss: {noteColor}");
|
||||
}
|
||||
}
|
||||
|
||||
controller?.StopMovement();
|
||||
@@ -470,6 +488,8 @@ public class HoldNote : BaseNote
|
||||
|
||||
if (segment == NoteSegment.Start)
|
||||
NotePool.Instance.ReturnStartNote(gameObject, noteColor);
|
||||
else if (segment == NoteSegment.End)
|
||||
NotePool.Instance.ReturnHoldNoteEndSegment(gameObject, noteColor);
|
||||
else
|
||||
NotePool.Instance.ReturnHoldNoteSegment(gameObject, noteColor);
|
||||
}
|
||||
@@ -487,7 +507,6 @@ public class HoldNote : BaseNote
|
||||
isJudged = false;
|
||||
isHoldActive = false; // 重置长按标记
|
||||
hasBeenHeldFromStart = false; // 重置
|
||||
// canJudgeThisSegment = false; // 此变量已被移除或不再关键
|
||||
|
||||
if (autoReturnCoroutine != null)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user