diff --git a/Assets/Scripts/Building.cs b/Assets/Scripts/Building.cs index c1b206e..dcc4ea2 100644 --- a/Assets/Scripts/Building.cs +++ b/Assets/Scripts/Building.cs @@ -200,6 +200,8 @@ namespace Northbound public TeamType GetTeam() => _team.Value; + public bool IsDead() => _currentHealth.Value <= 0; + public void SetTeam(TeamType team) { if (!IsServer) return; diff --git a/Assets/Scripts/Core.cs b/Assets/Scripts/Core.cs index e5bc493..f0e0f94 100644 --- a/Assets/Scripts/Core.cs +++ b/Assets/Scripts/Core.cs @@ -70,6 +70,8 @@ namespace Northbound #region ITeamMember Implementation + public bool IsDead() => _currentHealth.Value <= 0; + public TeamType GetTeam() { return TeamType.Player; // 코어는 플레이어 팀 diff --git a/Assets/Scripts/EnemyAIController.cs b/Assets/Scripts/EnemyAIController.cs index 13e1b04..5b0c62f 100644 --- a/Assets/Scripts/EnemyAIController.cs +++ b/Assets/Scripts/EnemyAIController.cs @@ -219,6 +219,14 @@ namespace Northbound return; } + // 타겟이 사망했는지 확인 + IDamageable damageable = targetPlayer.GetComponentInParent(); + if (damageable != null && damageable.IsDead()) + { + OnLostTarget(); + return; + } + float distanceToPlayer = Vector3.Distance(transform.position, targetPlayer.transform.position); Vector3 chaseReferencePoint = (aiType == TeamType.Monster) ? _chaseStartPosition : _originPosition; float distanceFromReference = Vector3.Distance(transform.position, chaseReferencePoint); @@ -251,6 +259,14 @@ namespace Northbound return; } + // 타겟이 사망했는지 확인 + IDamageable damageable = target.GetComponentInParent(); + if (damageable != null && damageable.IsDead()) + { + OnLostTarget(); + return; + } + // 핵심: ClosestPoint를 사용해 '벽 표면'까지의 실제 거리 계산 float distance = GetDistanceToTarget(target); @@ -312,6 +328,9 @@ namespace Northbound IDamageable damageable = col.GetComponentInParent(); if (damageable == null) continue; + // 이미 사망한 타겟은 제외 + if (damageable.IsDead()) continue; + ITeamMember teamMember = col.GetComponentInParent(); bool isAttackable = (teamMember != null && teamMember.GetTeam() == TeamType.Player) || (teamMember == null); if (!isAttackable) continue; @@ -371,7 +390,17 @@ namespace Northbound private GameObject GetTargetPlayer() { // 1순위: 물리적 참조 (장애물/서버 전용) - if (_cachedTargetPlayer != null && _cachedTargetPlayer.activeInHierarchy) return _cachedTargetPlayer; + if (_cachedTargetPlayer != null && _cachedTargetPlayer.activeInHierarchy) + { + // 사망 상태 체크 + IDamageable damageable = _cachedTargetPlayer.GetComponentInParent(); + if (damageable == null || damageable.IsDead()) + { + ClearTargetPlayer(); + return null; + } + return _cachedTargetPlayer; + } // 2순위: 네트워크 ID 검색 if (_targetPlayerId.Value != 0) @@ -379,6 +408,13 @@ namespace Northbound if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(_targetPlayerId.Value, out NetworkObject networkObject)) { _cachedTargetPlayer = networkObject.gameObject; + // 사망 상태 체크 + IDamageable damageable = _cachedTargetPlayer.GetComponentInParent(); + if (damageable != null && damageable.IsDead()) + { + ClearTargetPlayer(); + return null; + } return _cachedTargetPlayer; } } diff --git a/Assets/Scripts/EnemyPortal.cs b/Assets/Scripts/EnemyPortal.cs index 8bbc00e..ad46a08 100644 --- a/Assets/Scripts/EnemyPortal.cs +++ b/Assets/Scripts/EnemyPortal.cs @@ -199,9 +199,11 @@ using UnityEngine; currentCost *= (1f + costIncreaseRate / 100f); } - #region ITeamMember Implementation + #region ITeamMember Implementation - public TeamType GetTeam() => _team.Value; + public bool IsDead() => _currentHealth.Value <= 0; + + public TeamType GetTeam() => _team.Value; public void SetTeam(TeamType team) { diff --git a/Assets/Scripts/EnemyUnit.cs b/Assets/Scripts/EnemyUnit.cs index 9edb060..5af8285 100644 --- a/Assets/Scripts/EnemyUnit.cs +++ b/Assets/Scripts/EnemyUnit.cs @@ -132,6 +132,8 @@ namespace Northbound #region ITeamMember Implementation + public bool IsDead() => _currentHealth.Value <= 0; + public TeamType GetTeam() => _team.Value; public void SetTeam(TeamType team) diff --git a/Assets/Scripts/IDamageable.cs b/Assets/Scripts/IDamageable.cs index 17ca17f..27d32a8 100644 --- a/Assets/Scripts/IDamageable.cs +++ b/Assets/Scripts/IDamageable.cs @@ -6,5 +6,6 @@ namespace Northbound public interface IDamageable { void TakeDamage(int damage, ulong attackerId); + bool IsDead(); } } \ No newline at end of file