编队系统大更新 基本快搞好了 准备做敌人和分数

This commit is contained in:
FloatGaming
2025-11-10 22:41:13 +08:00
parent 7837c6adf0
commit 941b294fce
98 changed files with 8933 additions and 98 deletions
@@ -1,4 +1,5 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public enum NoteSegment { None, Start, Middle, End }
@@ -40,6 +41,8 @@ public class HoldNote : BaseNote
[Header("判定区间配置")]
public NoteJudgeConfig judgeConfig; // 判定区间配置,需在预制体或生成时赋值
private bool _hasTriggeredOnThisHold = false; // ensure single trigger per hold note
private void Awake()
{
controller = GetComponent<HoldNoteController>();
@@ -92,6 +95,8 @@ public class HoldNote : BaseNote
{
this.id = id;
this.trackIndex = trackIndex;
// also set BaseNote.TrackIndex so other systems using TrackIndex property work consistently
this.TrackIndex = trackIndex;
this.speed = speed;
this.startTime = time;
this.delay = delay;
@@ -346,6 +351,28 @@ public class HoldNote : BaseNote
JudgeManager.Instance.RegisterStartJudged(noteID, true);
isHoldActive = true; // 成功判定Start,长按状态激活
PlayHitAnimation();
// Trigger skills configured to fire on note hits for this slot when the Start is successfully hit.
if (!_hasTriggeredOnThisHold)
{
try
{
Debug.Log($"[HoldNote] Triggering SkillBuilder on START for slot {trackIndex} with result={result}");
// Prefer Hold type notification so skills expecting Hold can react. If it fails, fallback to Tap.
bool triggered = SkillBuilder.Instance?.NotifyNoteHit(this.trackIndex, result, SkillDefinition.NoteTypeTrigger.Hold) ?? false;
if (!triggered)
{
Debug.Log($"[HoldNote] START Hold notify did not trigger skill for slot {trackIndex}, trying Tap fallback");
triggered = SkillBuilder.Instance?.NotifyNoteHit(this.trackIndex, result, SkillDefinition.NoteTypeTrigger.Tap) ?? false;
}
Debug.Log($"[HoldNote] START skill trigger result for slot {trackIndex}: {triggered}");
}
catch (System.Exception ex)
{
Debug.LogError($"[HoldNote] NotifyNoteHit(Start) threw: {ex}");
}
_hasTriggeredOnThisHold = true; // avoid triggering again at End
}
}
else
{
@@ -353,8 +380,26 @@ public class HoldNote : BaseNote
Debug.Log($"[HoldNote] START Miss(偏差={offset:F2}秒): {noteColor}");
JudgeManager.Instance.RegisterStartJudged(noteID, false); // 明确标记未判定
isHoldActive = false; // Start Miss,长按状态不激活
// For Miss we should still notify shared logic once so it behaves like short notes
try
{
// Treat as Tap-type miss for compatibility
bool triggered = SkillBuilder.Instance?.NotifyNoteHit(this.trackIndex, result, SkillDefinition.NoteTypeTrigger.Tap) ?? false;
Debug.Log($"[HoldNote] START Miss NotifyNoteHit fired for slot {trackIndex}: {triggered}");
}
catch (System.Exception ex)
{
Debug.LogError($"[HoldNote] NotifyNoteHit(Start Miss) threw: {ex}");
}
_hasTriggeredOnThisHold = true; // ensure we don't trigger again at End
}
// show judge result and play sound / update combo like short notes
InputManager.Instance?.ShowJudgeResult(trackIndex, result);
JudgeSoundManager.Instance?.PlayJudgeSound(result);
teamUIController.Instance?.OnJudgeResult(result);
StartCoroutine(DelayedReturn());
}
@@ -442,6 +487,88 @@ public class HoldNote : BaseNote
}
InputManager.Instance?.ShowJudgeResult(trackIndex, result);
teamUIController.Instance?.OnJudgeResult(result); // 新增:更新combo计数
// Notify SkillBuilder so Hold notes can trigger skills configured for Hold
if (!_hasTriggeredOnThisHold)
{
var sb = SkillBuilder.Instance;
if (sb == null)
{
Debug.LogWarning($"[HoldNote] SkillBuilder.Instance is null when trying to notify for track {TrackIndex}");
}
else
{
var so = sb.GetAllyHeroSOBySlot(TrackIndex);
var def = so?.GetPrimarySkill();
Debug.Log($"[HoldNote] About to NotifyNoteHit: TrackIndex={TrackIndex} trackIndexField={trackIndex} so={(so!=null?so.name:"null")} skill={(def!=null?def.skillId:"null")} trigger={(def!=null?def.triggerCondition.ToString():"-")}");
}
bool triggeredHold = false;
bool triggeredTap = false;
// Build candidate slot indices to try: prefer instance field, then BaseNote.TrackIndex, then try to match UI slots
var candidates = new List<int>();
candidates.Add(this.trackIndex);
if (!candidates.Contains(this.TrackIndex)) candidates.Add(this.TrackIndex);
// try to resolve by matching this object to UI slots
var ui = teamUIController.Instance;
if (ui != null)
{
for (int i = 0; i < ui.allySlotIds.Count; i++)
{
var slotObj = ui.GetAllyObjectBySlot(i);
if (slotObj == null) continue;
if (slotObj == this.gameObject || this.gameObject.transform.IsChildOf(slotObj.transform))
{
if (!candidates.Contains(i)) candidates.Add(i);
break;
}
}
}
Debug.Log($"[HoldNote] NotifyNoteHit candidate slots: {string.Join(",", candidates)}");
// Try each candidate: prefer Hold notification. Stop on first successful trigger.
foreach (var slot in candidates)
{
try
{
triggeredHold = SkillBuilder.Instance?.NotifyNoteHit(slot, result, SkillDefinition.NoteTypeTrigger.Hold) ?? false;
}
catch (System.Exception ex)
{
Debug.LogError($"[HoldNote] NotifyNoteHit(Hold) threw for slot {slot}: {ex}");
}
if (triggeredHold)
{
Debug.Log($"[HoldNote] NotifyNoteHit succeeded (Hold) for slot {slot}");
break;
}
}
// If no candidate triggered via Hold, try Tap fallback on same candidate list
if (!triggeredHold)
{
foreach (var slot in candidates)
{
try
{
triggeredTap = SkillBuilder.Instance?.NotifyNoteHit(slot, result, SkillDefinition.NoteTypeTrigger.Tap) ?? false;
}
catch (System.Exception ex)
{
Debug.LogError($"[HoldNote] NotifyNoteHit(Tap) threw for slot {slot}: {ex}");
}
if (triggeredTap)
{
Debug.Log($"[HoldNote] NotifyNoteHit succeeded (Tap fallback) for slot {slot}");
break;
}
}
}
_hasTriggeredOnThisHold = true;
Debug.Log($"[HoldNote] Hold end NotifyNoteHit called: TrackIndex={TrackIndex} trackIndexField={trackIndex} result={result} triggeredHold={triggeredHold} triggeredTap={triggeredTap}");
}
Debug.Log($"[HoldNote] END判定结果: {noteColor} {result} (release={releaseTime:F2}, target={scheduledEndTime:F2})");
ReturnToPool();
}
@@ -507,6 +634,7 @@ public class HoldNote : BaseNote
isJudged = false;
isHoldActive = false; // 重置长按标记
hasBeenHeldFromStart = false; // 重置
_hasTriggeredOnThisHold = false; // 重置
if (autoReturnCoroutine != null)
{