113 lines
5.3 KiB
C#
113 lines
5.3 KiB
C#
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
/// <summary>
|
|
/// ⭐ 潜行Boss:ActivateBoss() 触发前处于"系统不存在"状态,三重隔离——
|
|
/// ① 不入鱼列表:CreateFishManager.OnlyFish 跳过 RegisterFishInstance(DeferFishRegister=true),
|
|
/// 自动锁定枚举/技能选鱼/服务端击杀通知全部找不到此Boss
|
|
/// ② 不可被打中:出场即禁用自身及全部子物体的 Collider2D
|
|
/// (子弹 BullitMove 命中走 Collider 触碰 tag=Fish,物理层关闭后子弹直接穿过)
|
|
/// ③ 不可被锁定:isLockable=false 双保险(不入字典本来也枚举不到)
|
|
/// 由外部(动画事件/入场演出结束回调/流程代码)调用 ActivateBoss() 后恢复正常:
|
|
/// 注册入鱼列表 + 恢复碰撞 + 允许锁定。
|
|
/// 潜行期走完路线 → 静默回池(不走 Id_DieFish_NotFX:不在字典只会打 NOT_FOUND 日志且不回收,会变野鱼)。
|
|
/// ⭐ 注意:潜行期不在鱼列表,新进房玩家的活鱼同步/全屏技能/冰冻均不包含此Boss,属预期行为;
|
|
/// 激活后才正常参与所有系统。
|
|
/// </summary>
|
|
public class StealthBossControl : DefaultBossControl
|
|
{
|
|
[Header("⭐ 潜行模式(激活前不入鱼列表/不可被打/不可被锁)")]
|
|
[Tooltip("true=出场后等待 ActivateBoss() 激活后才入列表/可被打/可被锁;false=行为与 DefaultBossControl 完全一致")]
|
|
public bool stealthUntilActivated = true;
|
|
|
|
/// <summary>是否已激活(已补注册+已恢复碰撞)。OnEnable 重置供池复用。</summary>
|
|
private bool _activated;
|
|
|
|
/// <summary>潜行期禁用的碰撞器缓存(激活时恢复)</summary>
|
|
private Collider2D[] _stealthCols;
|
|
/// <summary>各碰撞器出厂时的 enabled 状态(恢复时只恢复原本就启用的,出厂禁用的不动)</summary>
|
|
private bool[] _stealthColWasEnabled;
|
|
|
|
/// <summary>
|
|
/// ⭐ 指定激活方法:调用后 Boss 进入战斗状态——
|
|
/// 补注册入鱼列表(OnlyFish 同款入口,含 guid 冲突处理与创建日志)+ 恢复碰撞 + 允许锁定。
|
|
/// 由动画事件/演出回调/流程代码在合适的时机调用。重复调用安全;
|
|
/// stealthUntilActivated=false 时调用无任何副作用。
|
|
/// </summary>
|
|
public void ActivateBoss()
|
|
{
|
|
if (_activated) return;
|
|
_activated = true;
|
|
|
|
// ⓪ 解除"系统不存在"标记(isDead 兼作潜行标记,见 OnEnable 处注释)
|
|
isDead = false;
|
|
|
|
// ① 补注册入鱼列表(fishenum 在 OnlyFish/OnEnable 已赋值,与立即注册的鱼同源同值)
|
|
CreateFishManager.Instance.RegisterFishInstance(this, (int)fishenum);
|
|
|
|
// ② 恢复潜行期禁用的碰撞器(只恢复出厂就 enabled 的)
|
|
if (_stealthCols != null)
|
|
{
|
|
for (int i = 0; i < _stealthCols.Length; i++)
|
|
{
|
|
if (_stealthCols[i] != null && _stealthColWasEnabled[i])
|
|
_stealthCols[i].enabled = true;
|
|
}
|
|
_stealthCols = null;
|
|
_stealthColWasEnabled = null;
|
|
}
|
|
|
|
// ③ 允许锁定(触发 OnLockable 事件,GameMainPanel 自动锁定可订阅)
|
|
NotifyLockable();
|
|
}
|
|
|
|
public override void OnEnable()
|
|
{
|
|
base.OnEnable();
|
|
// ⭐ 池复用重置:每次出场重新进入潜行期,等外部再次 ActivateBoss()
|
|
_activated = false;
|
|
_stealthCols = null;
|
|
_stealthColWasEnabled = null;
|
|
|
|
if (!stealthUntilActivated) return;
|
|
|
|
// 潜行期:禁用自身及全部子物体碰撞器(true=含未激活的,出场特效的碰撞也一并关闭)
|
|
_stealthCols = GetComponentsInChildren<Collider2D>(true);
|
|
_stealthColWasEnabled = new bool[_stealthCols.Length];
|
|
for (int i = 0; i < _stealthCols.Length; i++)
|
|
{
|
|
_stealthColWasEnabled[i] = _stealthCols[i] != null && _stealthCols[i].enabled;
|
|
if (_stealthCols[i] != null)
|
|
_stealthCols[i].enabled = false;
|
|
}
|
|
|
|
// 锁定双保险(base.OnEnable 里 isLockable=!needLockEvent 可能已置 true,这里显式关掉)
|
|
isLockable = false;
|
|
|
|
// ⭐ 状态层兜底(拦手动锁定的关键):isDead=true 复用"死亡鱼不可打不可锁"的既定检查——
|
|
// - 手动锁定 HandleLock 不查字典/isLockable,只查 isDead → 这里必须置 true 才拦得住;
|
|
// - 子弹命中三处入口(BullitMove 碰撞/触发/AttackFish)同样只查 isDead → 潜行期子弹穿过;
|
|
// - 即使模型切换/特效在运行时动态激活了新的 Collider2D(不在 _stealthCols 缓存内),
|
|
// 状态层依然拦截,双保险不依赖碰撞器禁用是否完整。
|
|
// 激活时在 ActivateBoss ⓪ 复位为 false,池复用时 OnEnable 也复位(base.OnEnable)
|
|
isDead = true;
|
|
}
|
|
|
|
public override void OnMoveUpdata()
|
|
{
|
|
// ⭐ 潜行期走完路线:静默回池——
|
|
// 不在鱼列表,Id_DieFish_NotFX(guid) 只会打 NOT_FOUND 日志且不回收 → 变野鱼,
|
|
// 所以这里直接回池(isMove=false 防下一帧再进,Pool.Return 触发 OnDisable 复位)
|
|
if (stealthUntilActivated && !_activated
|
|
&& moveTime >= monsterData.moveLine.moveTime)
|
|
{
|
|
isMove = false;
|
|
Pool.Instance.Return(gameObject);
|
|
return;
|
|
}
|
|
|
|
base.OnMoveUpdata();
|
|
}
|
|
}
|