original ver 25/06/01

This commit is contained in:
GardeniaRabbit
2025-06-02 00:48:08 +08:00
committed by FloatGaming
commit 89e03899f0
1065 changed files with 183622 additions and 0 deletions
@@ -0,0 +1,320 @@
using System.Collections;
using UnityEngine;
public enum NoteSegment { None, Start, Middle, End }
[RequireComponent(typeof(HoldNoteController))]
public class HoldNote : BaseNote
{
private KeyCode keyToPress = KeyCode.None;
private string noteColor = string.Empty;
private string noteID = string.Empty;
private NoteSegment segment = NoteSegment.None;
private float hitTime = 0f;
private float releaseTime = 0f;
private bool hasReleased = true;
private bool hasEnteredLine = false;
private Coroutine autoReturnCoroutine;
private HoldNoteController controller;
public int id;
public int trackIndex;
public float speed;
public float startTime;
public float delay;
public bool isEnd;
public float scheduledEndTime;
public string color;
public KeyCode key;
public string type; // "start", "middle", or "end"
private void Awake()
{
controller = GetComponent<HoldNoteController>();
}
private void OnEnable()
{
ResetState();
}
public void Setup(int id, int trackIndex, float speed, float time, float delay,
bool isEnd, float scheduledEnd, string color, KeyCode key, string type)
{
this.id = id;
this.trackIndex = trackIndex;
this.speed = speed;
this.startTime = time;
this.delay = delay;
this.isEnd = isEnd;
this.scheduledEndTime = scheduledEnd;
this.color = color;
this.key = key;
this.type = type;
this.noteID = id.ToString();
this.keyToPress = key;
this.noteColor = color;
this.hitTime = time + delay;
this.segment = (delay == 0f) ? NoteSegment.Start :
(isEnd ? NoteSegment.End : NoteSegment.Middle);
this.hasEnteredLine = false;
this.hasReleased = false;
JudgeManager.Instance?.RegisterNoteReleased(noteID, false);
if (segment == NoteSegment.Start)
JudgeManager.Instance?.RegisterStartJudged(noteID, false);
if (segment == NoteSegment.End)
JudgeManager.Instance?.RegisterScheduledEndTime(noteID, scheduledEndTime);
controller?.SetSpeed(speed);
controller?.SetSegmentDelay(delay);
}
private void Update()
{
if (segment == NoteSegment.Start && Input.GetKeyDown(keyToPress))
{
if (hasEnteredLine)
HandleStart();
}
else if (segment == NoteSegment.End && Input.GetKeyUp(keyToPress))
{
HandleEnd();
}
if (segment == NoteSegment.Middle && hasEnteredLine)
{
if (JudgeManager.Instance.IsStartJudged(noteID) &&
!JudgeManager.Instance.HasNoteReleased(noteID) &&
Input.GetKey(keyToPress))
{
// 不再立即回收,由协程等待 hitTime 再回收
}
}
}
private void OnTriggerEnter2D(Collider2D collision)
{
if (!collision.CompareTag("JudgmentLine")) return;
if (segment == NoteSegment.Start || segment == NoteSegment.Middle)
{
hasEnteredLine = true;
}
if (segment == NoteSegment.Middle)
{
Debug.Log($"[HoldNote] Middle段进入判定线: color={noteColor}, isStartJudged={JudgeManager.Instance.IsStartJudged(noteID)}, hasReleased={JudgeManager.Instance.HasNoteReleased(noteID)}, isKeyDown={Input.GetKey(keyToPress)}");
if (autoReturnCoroutine != null)
StopCoroutine(autoReturnCoroutine);
autoReturnCoroutine = StartCoroutine(DelayedAutoReturnCheck());
}
if (segment == NoteSegment.End)
{
if (autoReturnCoroutine != null)
StopCoroutine(autoReturnCoroutine);
autoReturnCoroutine = StartCoroutine(DelayedAutoReturnCheck());
}
}
private void OnTriggerExit2D(Collider2D collision)
{
if (!collision.CompareTag("JudgmentLine")) return;
if (segment == NoteSegment.Start)
{
if (!JudgeManager.Instance.IsStartJudged(noteID))
{
ReturnToPool();
}
}
if (segment == NoteSegment.Middle)
{
if (!JudgeManager.Instance.IsStartJudged(noteID) ||
JudgeManager.Instance.HasNoteReleased(noteID))
{
Debug.Log($"[HoldNote] Middle段离开判定线强制回收: {noteColor}");
ReturnToPool();
}
}
else if (segment == NoteSegment.End)
{
if (!JudgeManager.Instance.IsStartJudged(noteID) || JudgeManager.Instance.HasNoteReleased(noteID))
{
ReturnToPool();
}
}
}
private IEnumerator DelayedAutoReturnCheck()
{
yield return null;
bool isStartJudgedBefore = JudgeManager.Instance.IsStartJudged(noteID);
bool isKeyHeldNow = Input.GetKey(keyToPress);
Debug.Log($"[HoldNote] 延迟检查开始: noteID={noteID}, color={noteColor}, isStartJudged={isStartJudgedBefore}, isKeyHeld={isKeyHeldNow}");
if (!isStartJudgedBefore && isKeyHeldNow)
{
Debug.Log($"[HoldNote] 延迟回补 Start 判定触发: {noteColor}");
HandleStart();
}
bool isStartJudged = JudgeManager.Instance.IsStartJudged(noteID);
bool hasReleased = JudgeManager.Instance.HasNoteReleased(noteID);
bool isKeyHeld = Input.GetKey(keyToPress);
Debug.Log($"[HoldNote] 延迟确认状态: isStartJudged={isStartJudged}, hasReleased={hasReleased}, isKeyHeld={isKeyHeld}");
if (segment == NoteSegment.Middle && isStartJudged && isKeyHeld)
{
float waitTime = Mathf.Max(0f, hitTime - Time.time);
Debug.Log($"[HoldNote] Middle段通过延迟确认,准备等待到 hitTime 回收: {noteColor}, 剩余时间={waitTime:F2}s");
yield return new WaitForSeconds(waitTime);
if (Input.GetKey(keyToPress) && !JudgeManager.Instance.HasNoteReleased(noteID))
{
Debug.Log($"[HoldNote] Middle段在 hitTime 达成条件,回收: {noteColor}");
ReturnToPool();
}
else
{
Debug.Log($"[HoldNote] Middle段在 hitTime 条件不符,不回收: {noteColor}");
}
}
else if (segment == NoteSegment.End && !hasReleased)
{
Debug.Log($"[HoldNote] End段延迟检查后仍未释放: {noteColor}");
}
else
{
Debug.Log($"[HoldNote] DelayedAutoReturnCheck 无需处理: segment={segment}, color={noteColor}");
}
}
private void HandleStart()
{
float pressTime = Time.time;
float offset = Mathf.Abs(pressTime - hitTime);
if (offset < 0.1f)
{
Debug.Log($"[HoldNote] START判定成功(偏差={offset:F2}秒): {noteColor}");
JudgeManager.Instance.RegisterStartJudged(noteID, true);
}
else
{
Debug.Log($"[HoldNote] START Miss(偏差={offset:F2}秒): {noteColor}");
}
StartCoroutine(DelayedReturn());
}
private IEnumerator DelayedReturn()
{
yield return new WaitForSeconds(0.05f);
ReturnToPool();
}
private void HandleEnd()
{
releaseTime = Time.time;
hasReleased = true;
JudgeManager.Instance.RegisterNoteReleased(noteID, true);
float diff = Mathf.Abs(releaseTime - scheduledEndTime);
string result;
if (releaseTime >= scheduledEndTime)
{
result = "Perfect";
}
else if (diff < 0.1f)
{
result = "Perfect";
}
else if (diff < 0.5f)
{
result = "Great";
}
else
{
result = "Good";
}
Debug.Log($"[HoldNote] END判定结果: {noteColor} {result} (release={releaseTime:F2}, target={scheduledEndTime:F2})");
ReturnToPool();
}
private void OnDisable()
{
if (autoReturnCoroutine != null)
{
StopCoroutine(autoReturnCoroutine);
autoReturnCoroutine = null;
}
if (segment == NoteSegment.End &&
!hasReleased &&
!JudgeManager.Instance.HasNoteReleased(noteID) &&
keyToPress != KeyCode.None &&
!Input.GetKey(keyToPress))
{
hasReleased = true;
JudgeManager.Instance.RegisterNoteReleased(noteID, true);
Debug.Log($"[HoldNote] OnDisable补偿KeyUp: {noteColor}");
}
controller?.StopMovement();
}
private void ReturnToPool()
{
if (!gameObject.activeSelf) return;
if (segment == NoteSegment.Start && !hasEnteredLine)
{
Debug.LogWarning($"[HoldNote] 阻止回收尚未进入判定线的 Start段: {noteColor}");
return;
}
gameObject.SetActive(false);
if (segment == NoteSegment.Start)
NotePool.Instance.ReturnStartNote(gameObject, noteColor);
else
NotePool.Instance.ReturnHoldNoteSegment(gameObject, noteColor);
}
public void ResetState()
{
hasReleased = false;
segment = NoteSegment.None;
keyToPress = KeyCode.None;
noteColor = string.Empty;
noteID = string.Empty;
hitTime = 0f;
scheduledEndTime = 0f;
hasEnteredLine = false;
if (autoReturnCoroutine != null)
{
StopCoroutine(autoReturnCoroutine);
autoReturnCoroutine = null;
}
controller?.StopMovement();
}
}