클라이언트에서 밝혀지지 않은 곳의 적이 보이는 문제 수정
This commit is contained in:
@@ -9,6 +9,12 @@ namespace Northbound
|
||||
[RequireComponent(typeof(Collider))]
|
||||
public class EnemyUnit : NetworkBehaviour, IDamageable, ITeamMember, IHealthProvider
|
||||
{
|
||||
[Header("Fog of War Visibility")]
|
||||
[Tooltip("전장의 안개에 의한 가시성 제어 활성화")]
|
||||
public bool enableFogVisibility = true;
|
||||
|
||||
[Tooltip("가시성 체크 주기 (초)")]
|
||||
public float visibilityCheckInterval = 0.1f;
|
||||
[Header("Team Settings")]
|
||||
[Tooltip("이 유닛의 팀 (Hostile = 적대세력, Monster = 몬스터)")]
|
||||
public TeamType enemyTeam = TeamType.Hostile;
|
||||
@@ -54,10 +60,20 @@ namespace Northbound
|
||||
|
||||
private UnitHealthBar _healthBar;
|
||||
|
||||
// 전장의 안개 가시성
|
||||
private Renderer[] _renderers;
|
||||
private float _visibilityTimer;
|
||||
private bool _lastVisibleState = true;
|
||||
private bool _initializedVisibility = false;
|
||||
private ulong _localPlayerId = ulong.MaxValue;
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
base.OnNetworkSpawn();
|
||||
|
||||
// 렌더러 캐시 (가시성 제어용)
|
||||
_renderers = GetComponentsInChildren<Renderer>();
|
||||
|
||||
if (IsServer)
|
||||
{
|
||||
_currentHealth.Value = maxHealth;
|
||||
@@ -72,6 +88,12 @@ namespace Northbound
|
||||
{
|
||||
CreateHealthBar();
|
||||
}
|
||||
|
||||
// 클라이언트에서는 기본적으로 렌더러 비활성화
|
||||
if (enableFogVisibility && IsClient)
|
||||
{
|
||||
SetRenderersEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public override void OnNetworkDespawn()
|
||||
@@ -80,6 +102,137 @@ namespace Northbound
|
||||
base.OnNetworkDespawn();
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
// 클라이언트에서만 가시성 체크 (호스트 포함)
|
||||
if (enableFogVisibility && IsClient)
|
||||
{
|
||||
UpdateFogVisibility();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 전장의 안개에 따른 가시성 업데이트 (클라이언트 전용)
|
||||
/// </summary>
|
||||
private void UpdateFogVisibility()
|
||||
{
|
||||
_visibilityTimer += Time.deltaTime;
|
||||
if (_visibilityTimer < visibilityCheckInterval) return;
|
||||
_visibilityTimer = 0f;
|
||||
|
||||
// 로컬 플레이어 ID 캐시
|
||||
if (_localPlayerId == ulong.MaxValue)
|
||||
{
|
||||
_localPlayerId = GetLocalPlayerId();
|
||||
if (_localPlayerId == ulong.MaxValue)
|
||||
{
|
||||
// 로컬 플레이어를 찾지 못함 - 기본적으로 숨김
|
||||
if (_initializedVisibility) return;
|
||||
_initializedVisibility = true;
|
||||
SetRenderersEnabled(false);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// FogOfWarSystem이 없으면 가시성 체크 안함
|
||||
if (FogOfWarSystem.Instance == null)
|
||||
{
|
||||
if (_initializedVisibility) return;
|
||||
_initializedVisibility = true;
|
||||
SetRenderersEnabled(false);
|
||||
return;
|
||||
}
|
||||
|
||||
// 현재 위치의 가시성 확인
|
||||
FogOfWarState state = FogOfWarSystem.Instance.GetVisibilityState(_localPlayerId, transform.position);
|
||||
bool shouldBeVisible = (state == FogOfWarState.Visible);
|
||||
|
||||
// 초기화되지 않은 경우 강제로 설정
|
||||
if (!_initializedVisibility)
|
||||
{
|
||||
_initializedVisibility = true;
|
||||
_lastVisibleState = shouldBeVisible;
|
||||
SetRenderersEnabled(shouldBeVisible);
|
||||
return;
|
||||
}
|
||||
|
||||
// 상태가 변경된 경우에만 렌더러 업데이트
|
||||
if (shouldBeVisible != _lastVisibleState)
|
||||
{
|
||||
_lastVisibleState = shouldBeVisible;
|
||||
SetRenderersEnabled(shouldBeVisible);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 로컬 플레이어의 실제 ID 가져오기
|
||||
/// </summary>
|
||||
private ulong GetLocalPlayerId()
|
||||
{
|
||||
if (NetworkManager.Singleton == null)
|
||||
{
|
||||
return ulong.MaxValue;
|
||||
}
|
||||
|
||||
// 방법 1: SpawnManager에서 찾기
|
||||
var localPlayer = NetworkManager.Singleton.SpawnManager.GetLocalPlayerObject();
|
||||
|
||||
// 방법 2: LocalClient에서 찾기
|
||||
if (localPlayer == null && NetworkManager.Singleton.LocalClient != null)
|
||||
{
|
||||
localPlayer = NetworkManager.Singleton.LocalClient.PlayerObject;
|
||||
}
|
||||
|
||||
// 방법 3: 직접 검색 (IsLocalPlayer인 플레이어 찾기)
|
||||
if (localPlayer == null)
|
||||
{
|
||||
var allPlayers = FindObjectsByType<NetworkPlayerController>(FindObjectsSortMode.None);
|
||||
foreach (var player in allPlayers)
|
||||
{
|
||||
if (player.IsLocalPlayer)
|
||||
{
|
||||
localPlayer = player.GetComponent<NetworkObject>();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (localPlayer == null)
|
||||
{
|
||||
return ulong.MaxValue;
|
||||
}
|
||||
|
||||
var playerController = localPlayer.GetComponent<NetworkPlayerController>();
|
||||
if (playerController == null)
|
||||
{
|
||||
return ulong.MaxValue;
|
||||
}
|
||||
|
||||
return playerController.OwnerPlayerId;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 모든 렌더러 활성화/비활성화
|
||||
/// </summary>
|
||||
private void SetRenderersEnabled(bool enabled)
|
||||
{
|
||||
if (_renderers == null) return;
|
||||
|
||||
foreach (var renderer in _renderers)
|
||||
{
|
||||
if (renderer != null)
|
||||
{
|
||||
renderer.enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
// 체력바도 함께 처리
|
||||
if (_healthBar != null)
|
||||
{
|
||||
_healthBar.gameObject.SetActive(enabled);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnHealthChanged(int previousValue, int newValue)
|
||||
{
|
||||
if (_healthBar != null)
|
||||
|
||||
Reference in New Issue
Block a user