refactor(enemy): 身体接触伤害改为常驻开启并与能力解耦
所有敌人默认常驻身体接触伤害:存活即开、死亡时经 PerformDeath 统一关碰撞体停止。 - ContactChaseAbility/AnimatedCeilingDropAbility 移除对 BodyContactDamage 的开关引用 - BodyContactDamage 语义改为常驻(更新注释) - 脚手架 SetupHurtAndContactBoxes 去掉 contactEnabled 参数恒为 true,并把 ContactDamageZone 的 HitBox._targetLayers 限定为 PlayerHurtBox(避免常驻后敌人互相误伤) - 7 个敌人预制体:E001 启用 BodyContactDamage;E002/E004/E005/ChaoFeng 补齐 ContactDamageZone(镜像 HurtBox 身体碰撞体);全部 _targetLayers 收敛为 PlayerHurtBox - 更新 Docs/Guides/02 敌人搭建指南 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -6,16 +6,14 @@ using UnityEngine;
|
||||
namespace BaseGames.Enemies.Abilities
|
||||
{
|
||||
/// <summary>
|
||||
/// 带动画的天花板跌落能力:播放 Fall 动画 + 切换物理体为 Dynamic 自由下落,落地后启用接触伤害并恢复巡逻。
|
||||
/// 带动画的天花板跌落能力:播放 Fall 动画 + 切换物理体为 Dynamic 自由下落,落地后恢复巡逻。
|
||||
/// 取代 sealed 的 CeilingDropAbility,动画所有权完整封装在本能力中。
|
||||
/// 可复用于任何需要从天花板落下并造成接触伤害的敌人。
|
||||
/// 可复用于任何需要从天花板落下的敌人。
|
||||
/// 身体接触伤害与本能力解耦:由常驻的 <see cref="BodyContactDamage"/> 全程负责,本能力不再开关它。
|
||||
/// </summary>
|
||||
[RequireComponent(typeof(Rigidbody2D))]
|
||||
public class AnimatedCeilingDropAbility : EnemyAbilityBase
|
||||
{
|
||||
[Header("落地后")]
|
||||
[SerializeField] private BodyContactDamage _contactDamage;
|
||||
|
||||
private AnimatedCeilingDropAbilitySO _cfg;
|
||||
private Rigidbody2D _rb;
|
||||
|
||||
@@ -53,10 +51,7 @@ namespace BaseGames.Enemies.Abilities
|
||||
}
|
||||
_rb.velocity = Vector2.zero;
|
||||
|
||||
// 落地后启用接触伤害
|
||||
if (_contactDamage != null)
|
||||
_contactDamage.enabled = true;
|
||||
|
||||
// 身体接触伤害由常驻 BodyContactDamage 全程负责,落地无需在此开启。
|
||||
yield return EnemyAbilityWaits.Get(_cfg.recoveryTime);
|
||||
|
||||
// PlayLocomotionClip(Patrol) 播放 AnimConfig.Walk(地面移动动画)
|
||||
@@ -73,8 +68,6 @@ namespace BaseGames.Enemies.Abilities
|
||||
{
|
||||
if (_rb != null)
|
||||
_rb.velocity = Vector2.zero;
|
||||
if (_contactDamage != null)
|
||||
_contactDamage.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,17 +5,15 @@ using UnityEngine;
|
||||
namespace BaseGames.Enemies.Abilities
|
||||
{
|
||||
/// <summary>
|
||||
/// 冲刺追击 + 体接触伤害能力:起手(Skill_Start 张口) → 朝玩家方向直冲(Skill_Loop 快速爬行 +
|
||||
/// 接触伤害),**直到撞墙/到平台边缘或玩家消失即停** → 收招(Skill_End)。一次冲刺为一次能力执行,
|
||||
/// 冲刺追击能力:起手(Skill_Start 张口) → 朝玩家方向直冲(Skill_Loop 快速爬行),
|
||||
/// **直到撞墙/到平台边缘或玩家消失即停** → 收招(Skill_End)。一次冲刺为一次能力执行,
|
||||
/// 结束后进入冷却(EnemyAbilitySO.cooldown);AI 追击态在冷却结束时经 EnsureAbility 重触发下一次冲刺。
|
||||
/// 冲刺方向在起手后按玩家所在侧一次性确定(committed 冲锋,会越过跳开的玩家,可被躲)。
|
||||
/// 追击动画由本能力全权驱动(Approach 步态不抢动画)。
|
||||
/// 身体接触伤害与本能力解耦:由常驻的 <see cref="BodyContactDamage"/> 全程负责,本能力不再开关它。
|
||||
/// </summary>
|
||||
public class ContactChaseAbility : EnemyAbilityBase
|
||||
{
|
||||
[Header("接触伤害")]
|
||||
[SerializeField] private BodyContactDamage _contactDamage;
|
||||
|
||||
private ContactChaseAbilitySO _cfg;
|
||||
|
||||
protected override void Awake()
|
||||
@@ -56,11 +54,10 @@ namespace BaseGames.Enemies.Abilities
|
||||
float speed = _cfg.dashSpeed > 0f ? _cfg.dashSpeed
|
||||
: (_enemy.Stats != null ? _enemy.Stats.RunSpeed : 0f);
|
||||
|
||||
// 冲刺:朝该方向直冲、接触伤害开、播 Skill_Loop,直到撞墙/到边缘或玩家消失即停。
|
||||
// 冲刺:朝该方向直冲、播 Skill_Loop,直到撞墙/到边缘或玩家消失即停。
|
||||
// (身体接触伤害由常驻 BodyContactDamage 全程负责,此处不再开关。)
|
||||
if (_cfg.loopClip.Clip != null)
|
||||
_animancer.Play(_cfg.loopClip);
|
||||
if (_contactDamage != null)
|
||||
_contactDamage.enabled = true;
|
||||
|
||||
float winX = _enemy.transform.position.x;
|
||||
float winT = 0f;
|
||||
@@ -82,14 +79,12 @@ namespace BaseGames.Enemies.Abilities
|
||||
_enemy.StopMovement();
|
||||
|
||||
// 收招 Skill_End;随后基类按 EnemyAbilitySO.cooldown 施加冷却。
|
||||
DisableContact();
|
||||
yield return PlaySkillEnd();
|
||||
Cleanup();
|
||||
}
|
||||
|
||||
protected override void OnInterrupted(InterruptReason reason)
|
||||
{
|
||||
DisableContact();
|
||||
// 丢失目标 = AI 主动退出追击态(ExternalRequest) → 播收招 Skill_End;
|
||||
// 受击/死亡/硬直等硬打断不播收招。协程已停,fire-and-forget;动画锁保证 Skill_End
|
||||
// 在其时长内不被巡逻步态盖掉。
|
||||
@@ -109,12 +104,6 @@ namespace BaseGames.Enemies.Abilities
|
||||
yield return EnemyAbilityWaits.Get(_cfg.endClip.Clip.length);
|
||||
}
|
||||
|
||||
private void DisableContact()
|
||||
{
|
||||
if (_contactDamage != null)
|
||||
_contactDamage.enabled = false;
|
||||
}
|
||||
|
||||
private void Cleanup()
|
||||
{
|
||||
_enemy.SetEngaged(false);
|
||||
|
||||
Reference in New Issue
Block a user