using Assets.MyGame.Scripts.Net.WebResponses; using UnityEngine; /// /// 烈焰风暴 Boss(精简版:只根据服务端 param 判定死亡/未死亡)。 /// /// param: { "isKill": bool, "beishu": int, "fishId": "...", "animId": int } /// animId==1 / isKill=false → 未死亡:炸一下 + bjEndUI,Boss 不消失,爆奖结束恢复游动 /// animId>=2 / isKill=true → 死亡:炸一下 + bjEndUI,Boss 消失 /// /// 无死鱼、无红包、无中间过程。 /// public class LieYanFengBao_BOSS : MonsterControl_BossBase { [Header("服务端参数解析")] [Tooltip("是否从 param 解析 isKill/animId(关闭则每次死亡都按死亡处理)")] public bool useServerParam = true; /// 爆奖事件引用 [System.NonSerialized] public LieYanFengBaoEvent currEvent; /// 当前死亡次数(仅日志用) private int _deathCount = 0; /// 缓存死亡位置(删除 Boss 后 transform 不可靠) private Vector3 _diePos; private bool _diePosCached = false; /// Boss 是否已从鱼列表回收(防重复回收) private bool _removed = false; /// 爆奖事件是否已 Init(决定特效实例由谁回收) private bool _awardInitCalled = false; public override void OnEnable() { base.OnEnable(); _deathCount = 0; _diePosCached = false; _removed = false; _awardInitCalled = false; currEvent = null; } public override void DieFish(RoomKillNotice obj = null) { _deathCount++; // ===== 解析服务端 param:animId 优先于 isKill ===== bool isKill; int beishu; if (useServerParam && obj?.param != null) { var p = BossKillParamParser.ParseMultiDeath(obj.param); if (p != null) { isKill = p.isKill; beishu = p.beishu > 0 ? p.beishu : (obj.beishu > 0 ? (int)obj.beishu : 1); if (p.animId >= 1) isKill = p.animId >= 2; Debug.Log($"[LieYanFengBao] DieFish 第{_deathCount}次(服务端) animId={p.animId} isKill={isKill} beishu={beishu} gold={obj.gold}"); } else { // param 解析失败:按死亡处理 isKill = true; beishu = obj.beishu > 0 ? (int)obj.beishu : 1; Debug.LogWarning($"[LieYanFengBao] param 解析失败,按死亡处理 beishu={beishu}"); } } else { // 老消息无 param:按死亡处理 isKill = true; beishu = obj?.beishu > 0 ? (int)obj.beishu : 1; Debug.Log($"[LieYanFengBao] DieFish 第{_deathCount}次(无param,按死亡) beishu={beishu}"); } // 缓存死亡位置(供爆奖特效定位) _diePos = transform.position; _diePosCached = true; // 炸一下 + bjEndUI(爆奖特效初始化回调,死亡/未死亡都播) action_effect_DieAward = (o) => InitAwardEffect(o, obj, beishu); if (isKill) { // ===== 死亡:Boss 消失 ===== isDieFish = true; if (obj != null) poolNum = (int)obj.gold; StartCoroutine(RemoveBossNextFrame()); } // 未死亡:不删除,等爆奖结束 OnAwardFinished 恢复游动 } /// 初始化爆奖事件(炸一下 + bjEndUI) private void InitAwardEffect(GameObject o, RoomKillNotice obj, int beishu) { Vector3 diePos = _diePosCached ? _diePos : transform.position; if (obj == null) return; foreach (var item in CreateFishManager.Instance.currGameType.list_Sits) { if (item.user == obj.userId) { _awardInitCalled = true; var v = o.GetComponent(); var evt = v as LieYanFengBaoEvent; if (evt != null) { evt.explosionCenter = diePos; evt.bossCtrl = this; currEvent = evt; } v.Init( obj.gold, item.posID, obj.skillsGold, obj.fishScore, beishu, JiaFen, () => { v.obj = obj.param; } ); break; } } } /// /// 下一帧删除 Boss:Ws_DieFish 在 DieFish 返回后同帧会实例化爆奖特效并触发回调。 /// 等到下一帧:Boss 被删除;爆奖事件没初始化(座位没找到)则把特效实例回池。 /// private System.Collections.IEnumerator RemoveBossNextFrame() { yield return null; if (!_removed) { _removed = true; if (!_awardInitCalled && currEffect_DieAward != null) { var effect = currEffect_DieAward; currEffect_DieAward = null; EffectPool.Instance.Return(effect); } CreateFishManager.Instance.Id_DieFish_NotFX(guid); Debug.Log($"[LieYanFengBao] Boss 已删除 guid={guid}"); } } /// 爆奖流程结束回调(Event 调用):未死亡时恢复游动 public void OnAwardFinished() { if (!isDieFish && isInitialized) { ChangeState(CharacterStateType.move); isMove = true; // ⭐ 复位死亡标记(同 XingJiXunHang):非最终死亡 Boss 不回池, // isDead 卡 true 会让锁定子弹被 BullitMove 判 target.isDead 立即 NotLock isDead = false; Debug.Log("[LieYanFengBao] 未死亡爆奖结束,恢复游动"); } currEvent = null; } private void OnDestroy() { StopAllCoroutines(); } }