fix(combat): HitBox 懒初始化,修复 Activate 早于 Awake 致接触判定碰撞体被禁用
BodyContactDamage.OnEnable 在 HitBox.Awake 之前调用 Activate 时 _directColliders 尚未收集,Activate 对空列表启用碰撞体、随后 Awake 又禁用碰撞体,导致接触伤害判定盒永久收不到 Trigger 事件、玩家不受碰撞伤害。原 BodyContactDamage 靠 Update 周期 re-Activate 掩盖了该时序问题,移除该循环后暴露。 将碰撞体/代理/服务缓存收集抽到 EnsureInitialized 懒初始化,Awake 与 Activate 都先调用,与脚本执行顺序无关。已实机验证:进入 Play 后碰撞体自动启用,玩家正常受到碰撞伤害。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -86,6 +86,8 @@ namespace BaseGames.Combat
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public void Activate(DamageSourceSO source = null, Transform attacker = null)
|
public void Activate(DamageSourceSO source = null, Transform attacker = null)
|
||||||
{
|
{
|
||||||
|
// 保证碰撞体已收集(防止 Activate 早于 Awake 调用时对空列表启用碰撞体)
|
||||||
|
EnsureInitialized();
|
||||||
_currentActivationId = _nextActivationId++;
|
_currentActivationId = _nextActivationId++;
|
||||||
_currentSource = source ?? _defaultSource;
|
_currentSource = source ?? _defaultSource;
|
||||||
_attackerTransform = attacker ?? transform;
|
_attackerTransform = attacker ?? transform;
|
||||||
@@ -115,8 +117,21 @@ namespace BaseGames.Combat
|
|||||||
if (source != null) _currentSource = source;
|
if (source != null) _currentSource = source;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Awake()
|
// 懒初始化标记:保证碰撞体收集只做一次,且不被 Awake / Activate 的调用顺序影响
|
||||||
|
private bool _initialized;
|
||||||
|
|
||||||
|
private void Awake() => EnsureInitialized();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 懒初始化:收集直属碰撞体 / 子代理 / 服务缓存,并将碰撞体置为禁用(默认关闭)。
|
||||||
|
/// Awake 与 Activate 都会调用——保证即使某组件(如 BodyContactDamage)因脚本执行顺序
|
||||||
|
/// 在本组件 Awake 之前就调用 Activate(),碰撞体列表也已就绪。否则 Activate 会对空列表
|
||||||
|
/// 启用碰撞体、随后 Awake 再把碰撞体禁用,导致判定盒永久收不到 Trigger 事件。
|
||||||
|
/// </summary>
|
||||||
|
private void EnsureInitialized()
|
||||||
{
|
{
|
||||||
|
if (_initialized) return;
|
||||||
|
_initialized = true;
|
||||||
// 收集本节点上所有直属 Collider2D,并验证 isTrigger
|
// 收集本节点上所有直属 Collider2D,并验证 isTrigger
|
||||||
_directColliders = GetComponents<Collider2D>();
|
_directColliders = GetComponents<Collider2D>();
|
||||||
foreach (var col in _directColliders)
|
foreach (var col in _directColliders)
|
||||||
|
|||||||
Reference in New Issue
Block a user