fix(combat): HitBox 命中节奏统一 + 投射物穿透可配
HitBox 新增 HitMode Single/Interval:Interval 用 Enter/Exit 跟踪占用 + Update 轮询,对停留目标按间隔重判,不再依赖 OnTriggerEnter 单次语义。BodyContactDamage 改用 Interval 模式,修复停留在接触判定内、无敌结束后不再受伤的 bug;FlyingEnemy 接触伤害加按目标间隔节流。ProjectileConfigSO 新增 MaxHits 默认 1 即命中即消失,Projectile 按命中预算回收,修掉默认无限穿透;弹反守卫避免反射后立即回收。 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -21,6 +21,12 @@ namespace BaseGames.Combat
|
||||
// Lifetime 在 Initialize 时缓存,避免 Update 每帧访问 SO 成员并做 null check
|
||||
private float _lifetime = float.MaxValue;
|
||||
|
||||
// 命中预算:剩余可命中次数(<=0 的 _maxHits 表示无限穿透)
|
||||
private int _maxHits = 1;
|
||||
private int _hitsRemaining;
|
||||
// 弹反帧标记:弹反命中不计入命中预算(避免反射后立即被回收)
|
||||
private bool _justReflected;
|
||||
|
||||
private PooledObject _pooledObject;
|
||||
|
||||
protected virtual void Awake()
|
||||
@@ -28,6 +34,8 @@ namespace BaseGames.Combat
|
||||
_rb = GetComponent<Rigidbody2D>();
|
||||
_hitBox = GetComponent<HitBox>();
|
||||
_pooledObject = GetComponent<PooledObject>();
|
||||
// 订阅命中确认:按命中预算决定何时回收(穿透 / 命中即消失)
|
||||
_hitBox.OnHitConfirmed += HandleHitConfirmed;
|
||||
}
|
||||
|
||||
/// <summary>从对象池取出后的初始化入口。</summary>
|
||||
@@ -38,6 +46,9 @@ namespace BaseGames.Combat
|
||||
DamageInfo = damageInfo;
|
||||
Direction = direction.normalized;
|
||||
_aliveTimer = 0f;
|
||||
_maxHits = config.MaxHits;
|
||||
_hitsRemaining = config.MaxHits;
|
||||
_justReflected = false;
|
||||
|
||||
SetFactionLayer(ownerLayer);
|
||||
_hitBox.Activate(config.DamageSource);
|
||||
@@ -71,6 +82,18 @@ namespace BaseGames.Combat
|
||||
// 重置 HitBox 命中记录,确保反射后可命中新目标
|
||||
_hitBox.Deactivate();
|
||||
_hitBox.Activate(_config?.DamageSource);
|
||||
|
||||
// 反射后重置命中预算,并跳过本次(弹反)命中的扣减,避免反射后立即被回收
|
||||
_hitsRemaining = _maxHits;
|
||||
_justReflected = true;
|
||||
}
|
||||
|
||||
/// <summary>HitBox 命中确认回调:按命中预算决定是否回收(穿透 / 命中即消失)。</summary>
|
||||
private void HandleHitConfirmed(DamageInfo _)
|
||||
{
|
||||
if (_maxHits <= 0) return; // 无限穿透:只靠寿命回收
|
||||
if (_justReflected) { _justReflected = false; return; } // 弹反命中不计入预算
|
||||
if (--_hitsRemaining <= 0) ReturnToPool();
|
||||
}
|
||||
|
||||
protected virtual void OnInitialized() { }
|
||||
|
||||
Reference in New Issue
Block a user