체력이 있는 오브젝트 사망 시, 적의 인식 대상에서 해제되도록 변경

This commit is contained in:
2026-02-19 16:06:01 +09:00
parent 3ed564eaa5
commit 72c2ec2884
6 changed files with 48 additions and 3 deletions

View File

@@ -200,6 +200,8 @@ namespace Northbound
public TeamType GetTeam() => _team.Value; public TeamType GetTeam() => _team.Value;
public bool IsDead() => _currentHealth.Value <= 0;
public void SetTeam(TeamType team) public void SetTeam(TeamType team)
{ {
if (!IsServer) return; if (!IsServer) return;

View File

@@ -70,6 +70,8 @@ namespace Northbound
#region ITeamMember Implementation #region ITeamMember Implementation
public bool IsDead() => _currentHealth.Value <= 0;
public TeamType GetTeam() public TeamType GetTeam()
{ {
return TeamType.Player; // 코어는 플레이어 팀 return TeamType.Player; // 코어는 플레이어 팀

View File

@@ -219,6 +219,14 @@ namespace Northbound
return; return;
} }
// 타겟이 사망했는지 확인
IDamageable damageable = targetPlayer.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsDead())
{
OnLostTarget();
return;
}
float distanceToPlayer = Vector3.Distance(transform.position, targetPlayer.transform.position); float distanceToPlayer = Vector3.Distance(transform.position, targetPlayer.transform.position);
Vector3 chaseReferencePoint = (aiType == TeamType.Monster) ? _chaseStartPosition : _originPosition; Vector3 chaseReferencePoint = (aiType == TeamType.Monster) ? _chaseStartPosition : _originPosition;
float distanceFromReference = Vector3.Distance(transform.position, chaseReferencePoint); float distanceFromReference = Vector3.Distance(transform.position, chaseReferencePoint);
@@ -251,6 +259,14 @@ namespace Northbound
return; return;
} }
// 타겟이 사망했는지 확인
IDamageable damageable = target.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsDead())
{
OnLostTarget();
return;
}
// 핵심: ClosestPoint를 사용해 '벽 표면'까지의 실제 거리 계산 // 핵심: ClosestPoint를 사용해 '벽 표면'까지의 실제 거리 계산
float distance = GetDistanceToTarget(target); float distance = GetDistanceToTarget(target);
@@ -312,6 +328,9 @@ namespace Northbound
IDamageable damageable = col.GetComponentInParent<IDamageable>(); IDamageable damageable = col.GetComponentInParent<IDamageable>();
if (damageable == null) continue; if (damageable == null) continue;
// 이미 사망한 타겟은 제외
if (damageable.IsDead()) continue;
ITeamMember teamMember = col.GetComponentInParent<ITeamMember>(); ITeamMember teamMember = col.GetComponentInParent<ITeamMember>();
bool isAttackable = (teamMember != null && teamMember.GetTeam() == TeamType.Player) || (teamMember == null); bool isAttackable = (teamMember != null && teamMember.GetTeam() == TeamType.Player) || (teamMember == null);
if (!isAttackable) continue; if (!isAttackable) continue;
@@ -371,7 +390,17 @@ namespace Northbound
private GameObject GetTargetPlayer() private GameObject GetTargetPlayer()
{ {
// 1순위: 물리적 참조 (장애물/서버 전용) // 1순위: 물리적 참조 (장애물/서버 전용)
if (_cachedTargetPlayer != null && _cachedTargetPlayer.activeInHierarchy) return _cachedTargetPlayer; if (_cachedTargetPlayer != null && _cachedTargetPlayer.activeInHierarchy)
{
// 사망 상태 체크
IDamageable damageable = _cachedTargetPlayer.GetComponentInParent<IDamageable>();
if (damageable == null || damageable.IsDead())
{
ClearTargetPlayer();
return null;
}
return _cachedTargetPlayer;
}
// 2순위: 네트워크 ID 검색 // 2순위: 네트워크 ID 검색
if (_targetPlayerId.Value != 0) if (_targetPlayerId.Value != 0)
@@ -379,6 +408,13 @@ namespace Northbound
if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(_targetPlayerId.Value, out NetworkObject networkObject)) if (NetworkManager.Singleton.SpawnManager.SpawnedObjects.TryGetValue(_targetPlayerId.Value, out NetworkObject networkObject))
{ {
_cachedTargetPlayer = networkObject.gameObject; _cachedTargetPlayer = networkObject.gameObject;
// 사망 상태 체크
IDamageable damageable = _cachedTargetPlayer.GetComponentInParent<IDamageable>();
if (damageable != null && damageable.IsDead())
{
ClearTargetPlayer();
return null;
}
return _cachedTargetPlayer; return _cachedTargetPlayer;
} }
} }

View File

@@ -199,9 +199,11 @@ using UnityEngine;
currentCost *= (1f + costIncreaseRate / 100f); 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) public void SetTeam(TeamType team)
{ {

View File

@@ -132,6 +132,8 @@ namespace Northbound
#region ITeamMember Implementation #region ITeamMember Implementation
public bool IsDead() => _currentHealth.Value <= 0;
public TeamType GetTeam() => _team.Value; public TeamType GetTeam() => _team.Value;
public void SetTeam(TeamType team) public void SetTeam(TeamType team)

View File

@@ -6,5 +6,6 @@ namespace Northbound
public interface IDamageable public interface IDamageable
{ {
void TakeDamage(int damage, ulong attackerId); void TakeDamage(int damage, ulong attackerId);
bool IsDead();
} }
} }