using System.Collections.Generic; using System; using UnityEngine; public class RecordPlayer { protected BattleField battleField; private Queue recordActionQueue = new Queue(); protected RecordAction currentRecordAction; protected List immediatelyActionList = new List(); private bool isWaitingNextAction = false; private float waitTimer = 0f; private const float waitInterval = 0.2f; private float speedRatio = 1.5f; private bool isForceFinish = false; public bool IsForceFinish { get { return isForceFinish; } } private bool stepForcefinish = false; public void Init(BattleField _battleField) { Release(); stepForcefinish = false; battleField = _battleField; } public bool IsPlaying() { bool isPlaying = currentRecordAction != null || recordActionQueue.Count > 0 || immediatelyActionList.Count > 0; //BattleDebug.LogError("IsPlaying " + isPlaying + " currentRecordAction " + (currentRecordAction != null) + " recordActionQueue.Count " + recordActionQueue.Count + " immediatelyActionList.Count " + immediatelyActionList.Count); return isPlaying; } public void PlayRecord(RecordAction recordAction) { if (recordAction == null) return; recordAction.actionOwner = this; // Debug.LogError("Enqueue record action " + recordAction.GetType() + " to queue"); if (isForceFinish || stepForcefinish) { recordAction.ForceFinish(); return; } recordActionQueue.Enqueue(recordAction); recordAction.AfterAddToQueue(); } public void PlayRecord(RecordAction recordAction, RecordAction waitingAnimeAction) { if (recordAction == null) return; recordAction.actionOwner = this; // Debug.LogError("Enqueue record action " + recordAction.GetType() + " to queue"); if (isForceFinish || stepForcefinish) { recordAction.ForceFinish(); return; } recordAction.waitingAnimeAction = waitingAnimeAction; recordActionQueue.Enqueue(recordAction); recordAction.AfterAddToQueue(); } public void PlayRecord(List recordActions) { for (int i = 0; i < recordActions.Count; i++) { PlayRecord(recordActions[i]); } } public void InsertRecord(RecordAction recordAction, int position = 0) { if (recordAction == null) return; recordAction.actionOwner = this; if (isForceFinish || stepForcefinish) { recordAction.ForceFinish(); return; } // Debug.LogError("Insert record action " + recordAction.GetType() + " at front of queue"); if (currentRecordAction != null) { Queue tempQueue = new Queue(); for (int i = 0; i < position && recordActionQueue.Count > 0; i++) { tempQueue.Enqueue(recordActionQueue.Dequeue()); } tempQueue.Enqueue(recordAction); while (recordActionQueue.Count > 0) { tempQueue.Enqueue(recordActionQueue.Dequeue()); } recordActionQueue = tempQueue; } else { recordActionQueue.Enqueue(recordAction); } recordAction.AfterAddToQueue(); } public void ImmediatelyPlay(RecordAction recordAction) { if (recordAction == null) return; recordAction.actionOwner = this; if (isForceFinish || stepForcefinish) { recordAction.ForceFinish(); return; } immediatelyActionList.Add(recordAction); } public void ImmediatelyPlay(RecordAction recordAction, RecordAction waitingAnimeAction) { if (recordAction == null) return; recordAction.actionOwner = this; if (isForceFinish || stepForcefinish) { recordAction.ForceFinish(); return; } recordAction.waitingAnimeAction = waitingAnimeAction; immediatelyActionList.Add(recordAction); } // 增强版本:支持父子关系和WaitingPlay标记 public void ImmediatelyPlay(RecordAction recordAction, RecordAction parentAction, bool isWaitingPlay) { if (recordAction == null) return; recordAction.actionOwner = this; if (isForceFinish || stepForcefinish) { recordAction.ForceFinish(); return; } // Debug.LogError("insert recordAction ImmediatelyPlay: " + recordAction.GetType().Name + " parentAction: " + (parentAction != null ? parentAction.GetType().Name : "null") + " isWaitingPlay: " + isWaitingPlay); // 设置父子关系 if (parentAction != null) { recordAction.SetParentAction(parentAction); parentAction.AddChildAction(recordAction); } // 设置WaitingPlay标记 recordAction.SetWaitingPlay(isWaitingPlay); immediatelyActionList.Add(recordAction); } public bool IsActionCompleted() { bool ret = true; foreach (var imac in immediatelyActionList) { if (!imac.IsActionCompleted()) { ret = false; break; } } if (ret == false) { return false; } if (currentRecordAction != null && !currentRecordAction.IsActionCompleted()) { return false; } return ret; } protected void ImmediatelyPlayRun() { if (immediatelyActionList.Count > 0) { List removeIndexList = new List(); // 关键修复:从前往后遍历,确保按加入顺序执行 for (int i = 0; i < immediatelyActionList.Count; i++) { var action = immediatelyActionList[i]; if (action == null) { removeIndexList.Add(i); continue; } // 检查是否可以开始执行(WaitingPlay条件检查) if (!action.CanStartExecution()) { continue; } // 检查同级的前置兄弟节点:如果有相同父节点且索引更小的节点还在执行,则等待 bool shouldWaitForSibling = false; if (action.isWaitingPlay && action.parentAction != null) { for (int j = 0; j < i; j++) { var prevAction = immediatelyActionList[j]; if (prevAction != null && prevAction.parentAction == action.parentAction) { // 找到同级前置节点,如果它还在执行中,则当前节点需要等待 if (!prevAction.IsFinished() && action.NeedWaitSibling()) { shouldWaitForSibling = true; // BattleDebug.LogError($"RecordPlayer: {action.GetType().Name} 等待同级前置节点 {prevAction.GetType().Name} 完成"); break; } } } } if (shouldWaitForSibling) { continue; } if (!action.IsFinished()) { if (action.waitingAnimeAction != null) { if (!action.waitingAnimeAction.IsActionCompleted()) { continue; } } action.Run(); continue; } removeIndexList.Add(i); } // 从后往前删除,确保索引不会因为删除而错位 for (int i = removeIndexList.Count - 1; i >= 0; i--) { int index = removeIndexList[i]; if (index < 0 || index >= immediatelyActionList.Count) continue; immediatelyActionList.RemoveAt(index); } } } public virtual void Run() { ImmediatelyPlayRun(); // 等待下一个action if (isWaitingNextAction) { waitTimer += Time.deltaTime * speedRatio; if (waitTimer >= waitInterval) { isWaitingNextAction = false; waitTimer = 0f; } else { return; } } if (currentRecordAction == null) { if (recordActionQueue.Count <= 0) { return; } } if (currentRecordAction != null && !currentRecordAction.IsFinished()) { if (currentRecordAction.waitingAnimeAction != null) { if (!currentRecordAction.waitingAnimeAction.IsActionCompleted()) { return; } } currentRecordAction.Run(); return; } if (currentRecordAction != null && currentRecordAction.IsFinished()) { var guid = currentRecordAction.GetBattleFieldGuid(); // BattleDebug.LogError("record action " + currentRecordAction.GetType() + " play finished"); currentRecordAction = null; isWaitingNextAction = true; waitTimer = 0f; EventBroadcast.Instance.Broadcast(EventName.RECORDPLAYER_END, guid); return; } if (currentRecordAction == null) { if (recordActionQueue.Count > 0) { currentRecordAction = recordActionQueue.Dequeue(); #if UNITY_EDITOR // if (currentRecordAction is SkillRecordAction skillRecordAction) // { // Debug.LogError("RecordPlayer Run Play SkillRecordAction skillname " + skillRecordAction.skillBase.skillConfig.SkillName + " caster " + skillRecordAction.skillBase.caster.teamHero.name); // } // else #endif { BattleDebug.LogError("play record action " + currentRecordAction.GetType()); } } } } // 先预留 感觉用的上 public virtual void ResumeGame() { } public virtual void PauseGame() { } public void HaveRest() { ForceFinish(); } public void ClearAllRecordAction() { currentRecordAction?.ForceFinish(); currentRecordAction = null; recordActionQueue.Clear(); immediatelyActionList.Clear(); } public void EnableForceFinish(bool enable) { stepForcefinish = enable; } public void ForceFinish() { isForceFinish = true; for (int i = immediatelyActionList.Count - 1; i >= 0; i--) { var action = immediatelyActionList[i]; action.ForceFinish(); immediatelyActionList.Remove(action); } while (currentRecordAction != null) { var temp = currentRecordAction; currentRecordAction = null; temp.ForceFinish(); } while (recordActionQueue.Count > 0) { recordActionQueue.Dequeue().ForceFinish(); } } public void Release() { if (null != currentRecordAction) { currentRecordAction.ForceFinish(); } currentRecordAction = null; recordActionQueue.Clear(); immediatelyActionList.Clear(); isForceFinish = false; stepForcefinish = false; } public void SetSpeedRatio(float ratio) { speedRatio = ratio; } }