feat: Add HurtBoxOwnerGuard to prevent multiple damage registrations from the same HitBox activation
- Implemented HurtBoxOwnerGuard to ensure that multiple HurtBoxes on the same character do not register damage multiple times during a single HitBox activation. - Added custom editor for HitBox to facilitate the creation of shape colliders with HitBoxColliderProxy. - Introduced PhysicsPerceptionSystem for enemy perception, supporting multiple detection modes including RangeCircle, BatchLOS, FanCast, and BoxCast. - Created EnemyPatrolZone to define patrol and chase areas for enemies, allowing for shared zones among multiple enemies. - Added BD_IsOutsideZone conditional task for Behavior Designer to check if an enemy or player is outside a defined patrol zone.
This commit is contained in:
@@ -45,6 +45,7 @@ namespace BaseGames.Enemies.Navigation
|
||||
// ── 私有 ────────────────────────────────────────────────────────
|
||||
private NavAgent _navAgent;
|
||||
private TransformBasedMovement _movement;
|
||||
private EnemyMovement _enemyMovement;
|
||||
|
||||
// 能力 handler 注册表(NavLinkType → INavLinkHandler)
|
||||
private readonly Dictionary<NavLinkType, INavLinkHandler> _handlers
|
||||
@@ -53,6 +54,7 @@ namespace BaseGames.Enemies.Navigation
|
||||
|
||||
// 连接段状态缓存
|
||||
private NavLinkType _currentLinkType = NavLinkType.None;
|
||||
private bool _wasNavOnSegment;
|
||||
private Vector2 _currentLinkStart;
|
||||
private Vector2 _currentLinkEnd;
|
||||
|
||||
@@ -61,6 +63,7 @@ namespace BaseGames.Enemies.Navigation
|
||||
{
|
||||
_navAgent = GetComponent<NavAgent>();
|
||||
_movement = GetComponent<TransformBasedMovement>();
|
||||
_enemyMovement = GetComponent<EnemyMovement>();
|
||||
|
||||
// 自动发现 INavLinkHandler 组件并注册(包含子对象)
|
||||
foreach (var handler in GetComponentsInChildren<INavLinkHandler>(true))
|
||||
@@ -196,6 +199,32 @@ namespace BaseGames.Enemies.Navigation
|
||||
private void HandlePathFailed(NavAgent _) => OnNavPathFailed?.Invoke();
|
||||
private void HandleGoalReached(NavAgent _) => OnGoalReached?.Invoke();
|
||||
|
||||
// ── NavDriving 信号桥 ───────────────────────────────────────────
|
||||
/// <summary>
|
||||
/// 每物理帧向 <see cref="EnemyMovement"/> 写入导航方向信号,并设置 NavDriving 标志。
|
||||
/// NavDriving=true 时 EnemyMovement 只更新朝向,TBM 保留对 transform.position 的控制权。
|
||||
/// </summary>
|
||||
private void FixedUpdate()
|
||||
{
|
||||
if (_enemyMovement == null || _navAgent == null) return;
|
||||
|
||||
bool onSegment = _navAgent.IsMovingOnSegment;
|
||||
_enemyMovement.NavDriving = onSegment;
|
||||
|
||||
if (onSegment)
|
||||
{
|
||||
float dx = _navAgent.PathSubGoal.x - transform.position.x;
|
||||
_enemyMovement.PendingInput.MoveDir = Mathf.Abs(dx) > 0.01f ? Mathf.Sign(dx) : 0f;
|
||||
}
|
||||
else if (_wasNavOnSegment && !_navAgent.IsFollowingAPath)
|
||||
{
|
||||
// 导航刚结束(到达目标 / 路径失败)→ 清除残留 MoveDir
|
||||
_enemyMovement.PendingInput.WantStop = true;
|
||||
}
|
||||
|
||||
_wasNavOnSegment = onSegment;
|
||||
}
|
||||
|
||||
// ── 工具 ───────────────────────────────────────────────────────
|
||||
private static NavLinkType ParseLinkType(string name) => name switch
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user