플레이어 사망 시, 소지 중인 모든 자원을 드랍하도록 함

This commit is contained in:
2026-02-19 16:04:45 +09:00
parent 01e7291bed
commit 411913520b

View File

@@ -22,6 +22,10 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
[SerializeField] private GameObject damageEffectPrefab; [SerializeField] private GameObject damageEffectPrefab;
[SerializeField] private GameObject deathEffectPrefab; [SerializeField] private GameObject deathEffectPrefab;
[Header("Death Settings")]
[SerializeField] private GameObject resourcePickupPrefab; // 자원 드랍 프리팹
[SerializeField] private float respawnDelay = 10f; // 부활 대기 시간 (초)
// 이 플레이어를 제어하는 클라이언트 ID (서버 소유권이지만 논리적 소유자) // 이 플레이어를 제어하는 클라이언트 ID (서버 소유권이지만 논리적 소유자)
private NetworkVariable<ulong> _ownerPlayerId = new NetworkVariable<ulong>( private NetworkVariable<ulong> _ownerPlayerId = new NetworkVariable<ulong>(
ulong.MaxValue, ulong.MaxValue,
@@ -239,10 +243,71 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
} }
} }
/// <summary>
/// 플레이어가 가진 자원을 ResourcePickup으로 드랍
/// </summary>
private void DropPlayerResources()
{
if (!IsServer) return;
// ServerResourceManager에서 플레이어의 자원 확인
var resourceManager = ServerResourceManager.Instance;
if (resourceManager == null || resourcePickupPrefab == null)
return;
ulong playerId = _ownerPlayerId.Value;
int resourceAmount = resourceManager.GetPlayerResourceAmount(playerId);
if (resourceAmount > 0)
{
// 자원을 0으로 설정 (드랍 후 소멸)
resourceManager.RemoveResource(playerId, resourceAmount);
// 플레이어의 UI 업데이트 요청
var spawnedObjects = NetworkManager.Singleton.SpawnManager.SpawnedObjects;
foreach (var kvp in spawnedObjects)
{
var controller = kvp.Value.GetComponent<NetworkPlayerController>();
if (controller != null && controller.OwnerPlayerId == playerId)
{
var inventory = kvp.Value.GetComponent<PlayerResourceInventory>();
if (inventory != null)
{
inventory.RequestResourceUpdateServerRpc(playerId);
break;
}
}
}
// ResourcePickup 프리팹 생성
GameObject pickupObj = Instantiate(resourcePickupPrefab, transform.position + Vector3.up, Quaternion.identity);
NetworkObject pickupNetworkObj = pickupObj.GetComponent<NetworkObject>();
ResourcePickup pickup = pickupObj.GetComponent<ResourcePickup>();
if (pickupNetworkObj != null && pickup != null)
{
// 드랍된 자원량 설정
pickup.resourceAmount = resourceAmount;
pickup.resourceName = "Dropped Resource";
// NetworkObject로 스폰
pickupNetworkObj.Spawn();
}
else
{
Debug.LogError("[NetworkPlayerController] ResourcePickup 프리팹이 올바르지 않습니다.");
Destroy(pickupObj);
}
}
}
private void Die(ulong killerId) private void Die(ulong killerId)
{ {
if (!IsServer) return; if (!IsServer) return;
// 플레이어가 가진 자원을 ResourcePickup으로 드랍
DropPlayerResources();
// 사망 이펙트 // 사망 이펙트
ShowDeathEffectClientRpc(); ShowDeathEffectClientRpc();
@@ -252,8 +317,51 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
_networkAnimator.SetTrigger("Die"); _networkAnimator.SetTrigger("Die");
} }
// 일정 시간 후 리스폰 또는 디스폰 // 사망 즉시 플레이어를 숨김 (크립의 감지 방지)
Invoke(nameof(HandleDeath), 3f); HidePlayerClientRpc();
// 일정 시간 후 리스폰
Invoke(nameof(HandleDeath), respawnDelay);
}
/// <summary>
/// 사망 시 플레이어 숨김
/// </summary>
[ClientRpc]
private void HidePlayerClientRpc()
{
// CharacterController 비활성화 (이동 및 충돌 방지)
if (_controller != null)
{
_controller.enabled = false;
}
// 모든 Renderer 비활성화 (시각적으로 숨김)
Renderer[] renderers = GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
renderer.enabled = false;
}
}
/// <summary>
/// 리스폰 시 플레이어 다시 보임
/// </summary>
[ClientRpc]
private void ShowPlayerClientRpc()
{
// CharacterController 활성화
if (_controller != null)
{
_controller.enabled = true;
}
// 모든 Renderer 활성화
Renderer[] renderers = GetComponentsInChildren<Renderer>();
foreach (Renderer renderer in renderers)
{
renderer.enabled = true;
}
} }
private void HandleDeath() private void HandleDeath()
@@ -284,6 +392,9 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl
{ {
_networkAnimator.SetTrigger("Revive"); _networkAnimator.SetTrigger("Revive");
} }
// 플레이어 다시 보임 (이동 후 실행)
ShowPlayerClientRpc();
} }
[ClientRpc] [ClientRpc]