using System; using System.Collections.Generic; using System.Linq; using Cysharp.Threading.Tasks; using UnityEngine; public class BattleEffectMgr { private BattleField battleField; private Dictionary> effectDict = new Dictionary>(); // 缓存Run()的临时列表,避免每帧分配 private List _runList = new List(); public void Init(BattleField _battleField) { Reload(_battleField); } public void Reload(BattleField _battleField) { Release(); battleField = _battleField; } public void Run() { _runList.Clear(); foreach (KeyValuePair> kvPair in effectDict) { _runList.AddRange(kvPair.Value); } for (int i = _runList.Count - 1; i >= 0; i--) { BattleEffectPlayer effectPlayer = _runList[i]; if (effectPlayer != null) { effectPlayer.Run(); } } } public void PauseGame() { foreach (KeyValuePair> kvPair in effectDict) { foreach (BattleEffectPlayer effectPlayer in kvPair.Value) { if (effectPlayer != null) { effectPlayer.Pause(); } } } } public void ResumeGame() { foreach (KeyValuePair> kvPair in effectDict) { foreach (BattleEffectPlayer effectPlayer in kvPair.Value) { if (effectPlayer != null) { effectPlayer.Resume(); } } } } public BattleEffectPlayer PlayEffect(BattleObject layerDepender, int effectId, Transform parent, BattleCamp camp, float _scaleRatio) { if (effectId <= 0) { Debug.LogError("effect id <= 0"); return null; } var effectCfg = EffectConfig.Get(effectId); if (null == effectCfg) { Debug.LogError("effect config is null, effectId : " + effectId); return null; } if (!effectDict.ContainsKey(effectId)) { effectDict[effectId] = new List(); } bool isRedCamp = camp == BattleCamp.Red; BattleEffectPlayer effectPlayer = BattleEffectPlayer.Create(effectId, battleField, battleField.battleRootNode.transform, isRedCamp, _scaleRatio); // 设置特效缩放和方向 effectPlayer.transform.position = parent.position; BattleObject temp = layerDepender; effectPlayer.onDestroy += (efPlayer) => { OnEffectDestroy(efPlayer); temp.layerMgr.RemoveEffect(efPlayer); }; if (effectPlayer != null) { effectDict[effectId].Add(effectPlayer); } effectPlayer.SetSpeedRatio(battleField.speedRatio); effectPlayer.Play(true).Forget(); effectPlayer.SetScaleX(isRedCamp ? 1 : -1); // var effectScale = effectPlayer.transform.localScale; // effectScale.x *= isRedCamp ? 1 : -1; // effectPlayer.transform.localScale = effectScale; if (null != layerDepender) { layerDepender.layerMgr.AddEffect(effectPlayer); } return effectPlayer; } public void RemoveEffect(int effectId, BattleEffectPlayer effectPlayer) { List effectPlayers = null; if (effectDict.TryGetValue(effectId, out effectPlayers)) { effectPlayers.Remove(effectPlayer); if (null == effectPlayer) { BattleDebug.LogError("effect player is null, effectid : " + effectId); return; } if (null != effectPlayer.gameObject) { GameObject.DestroyImmediate(effectPlayer.gameObject); } effectPlayer = null; } else { BattleDebug.LogError("could not find effect in list, effectid : " + effectId); } } protected void OnEffectDestroy(BattleEffectPlayer effectPlayer) { if (effectDict.ContainsKey(effectPlayer.effectId)) { effectDict[effectPlayer.effectId].Remove(effectPlayer); if (effectDict[effectPlayer.effectId].Count == 0) { effectDict.Remove(effectPlayer.effectId); } } } public void HaveRest() { Release(); } public void Release() { // 必须先快照key列表,因为DestroyImmediate会同步触发OnEffectDestroy修改effectDict _runList.Clear(); var keys = new List(effectDict.Keys); for (int k = 0; k < keys.Count; k++) { if (!effectDict.TryGetValue(keys[k], out var effectPlayers)) continue; while (effectPlayers.Count > 0) { var effectPlayer = effectPlayers[0]; if (effectPlayer != null) { GameObject.DestroyImmediate(effectPlayer.gameObject); } else { effectPlayers.RemoveAt(0); } } } effectDict.Clear(); } public void SetSpeedRatio(float ratio) { foreach (var kvPair in effectDict) { foreach (var effectPlayer in kvPair.Value) { effectPlayer.SetSpeedRatio(ratio); } } } }