From 8a0992c0e7dee1bfcd162bbc462db0b30f0272e2 Mon Sep 17 00:00:00 2001 From: Joywayer Date: Thu, 11 Jun 2026 16:56:42 +0800 Subject: [PATCH] =?UTF-8?q?fix(combat):=20HitBox=20=E6=87=92=E5=88=9D?= =?UTF-8?q?=E5=A7=8B=E5=8C=96=EF=BC=8C=E4=BF=AE=E5=A4=8D=20Activate=20?= =?UTF-8?q?=E6=97=A9=E4=BA=8E=20Awake=20=E8=87=B4=E6=8E=A5=E8=A7=A6?= =?UTF-8?q?=E5=88=A4=E5=AE=9A=E7=A2=B0=E6=92=9E=E4=BD=93=E8=A2=AB=E7=A6=81?= =?UTF-8?q?=E7=94=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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) --- Assets/_Game/Scripts/Combat/HitBox.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/Assets/_Game/Scripts/Combat/HitBox.cs b/Assets/_Game/Scripts/Combat/HitBox.cs index 2cb1b7f..54929f8 100644 --- a/Assets/_Game/Scripts/Combat/HitBox.cs +++ b/Assets/_Game/Scripts/Combat/HitBox.cs @@ -86,6 +86,8 @@ namespace BaseGames.Combat /// public void Activate(DamageSourceSO source = null, Transform attacker = null) { + // 保证碰撞体已收集(防止 Activate 早于 Awake 调用时对空列表启用碰撞体) + EnsureInitialized(); _currentActivationId = _nextActivationId++; _currentSource = source ?? _defaultSource; _attackerTransform = attacker ?? transform; @@ -115,8 +117,21 @@ namespace BaseGames.Combat if (source != null) _currentSource = source; } - private void Awake() + // 懒初始化标记:保证碰撞体收集只做一次,且不被 Awake / Activate 的调用顺序影响 + private bool _initialized; + + private void Awake() => EnsureInitialized(); + + /// + /// 懒初始化:收集直属碰撞体 / 子代理 / 服务缓存,并将碰撞体置为禁用(默认关闭)。 + /// Awake 与 Activate 都会调用——保证即使某组件(如 BodyContactDamage)因脚本执行顺序 + /// 在本组件 Awake 之前就调用 Activate(),碰撞体列表也已就绪。否则 Activate 会对空列表 + /// 启用碰撞体、随后 Awake 再把碰撞体禁用,导致判定盒永久收不到 Trigger 事件。 + /// + private void EnsureInitialized() { + if (_initialized) return; + _initialized = true; // 收集本节点上所有直属 Collider2D,并验证 isTrigger _directColliders = GetComponents(); foreach (var col in _directColliders)