From 411913520b5eb42dc3eb35c1fe5a2374b73f1535 Mon Sep 17 00:00:00 2001 From: dal4segno Date: Thu, 19 Feb 2026 16:04:45 +0900 Subject: [PATCH] =?UTF-8?q?=ED=94=8C=EB=A0=88=EC=9D=B4=EC=96=B4=20?= =?UTF-8?q?=EC=82=AC=EB=A7=9D=20=EC=8B=9C,=20=EC=86=8C=EC=A7=80=20?= =?UTF-8?q?=EC=A4=91=EC=9D=B8=20=EB=AA=A8=EB=93=A0=20=EC=9E=90=EC=9B=90?= =?UTF-8?q?=EC=9D=84=20=EB=93=9C=EB=9E=8D=ED=95=98=EB=8F=84=EB=A1=9D=20?= =?UTF-8?q?=ED=95=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Assets/Scripts/NetworkPlayerController.cs | 115 +++++++++++++++++++++- 1 file changed, 113 insertions(+), 2 deletions(-) diff --git a/Assets/Scripts/NetworkPlayerController.cs b/Assets/Scripts/NetworkPlayerController.cs index 5e3fe7d..4413146 100644 --- a/Assets/Scripts/NetworkPlayerController.cs +++ b/Assets/Scripts/NetworkPlayerController.cs @@ -22,6 +22,10 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl [SerializeField] private GameObject damageEffectPrefab; [SerializeField] private GameObject deathEffectPrefab; + [Header("Death Settings")] + [SerializeField] private GameObject resourcePickupPrefab; // 자원 드랍 프리팹 + [SerializeField] private float respawnDelay = 10f; // 부활 대기 시간 (초) + // 이 플레이어를 제어하는 클라이언트 ID (서버 소유권이지만 논리적 소유자) private NetworkVariable _ownerPlayerId = new NetworkVariable( ulong.MaxValue, @@ -239,10 +243,71 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl } } + /// + /// 플레이어가 가진 자원을 ResourcePickup으로 드랍 + /// + 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(); + if (controller != null && controller.OwnerPlayerId == playerId) + { + var inventory = kvp.Value.GetComponent(); + if (inventory != null) + { + inventory.RequestResourceUpdateServerRpc(playerId); + break; + } + } + } + + // ResourcePickup 프리팹 생성 + GameObject pickupObj = Instantiate(resourcePickupPrefab, transform.position + Vector3.up, Quaternion.identity); + NetworkObject pickupNetworkObj = pickupObj.GetComponent(); + ResourcePickup pickup = pickupObj.GetComponent(); + + 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) { if (!IsServer) return; + // 플레이어가 가진 자원을 ResourcePickup으로 드랍 + DropPlayerResources(); + // 사망 이펙트 ShowDeathEffectClientRpc(); @@ -252,8 +317,51 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl _networkAnimator.SetTrigger("Die"); } - // 일정 시간 후 리스폰 또는 디스폰 - Invoke(nameof(HandleDeath), 3f); + // 사망 즉시 플레이어를 숨김 (크립의 감지 방지) + HidePlayerClientRpc(); + + // 일정 시간 후 리스폰 + Invoke(nameof(HandleDeath), respawnDelay); + } + + /// + /// 사망 시 플레이어 숨김 + /// + [ClientRpc] + private void HidePlayerClientRpc() + { + // CharacterController 비활성화 (이동 및 충돌 방지) + if (_controller != null) + { + _controller.enabled = false; + } + + // 모든 Renderer 비활성화 (시각적으로 숨김) + Renderer[] renderers = GetComponentsInChildren(); + foreach (Renderer renderer in renderers) + { + renderer.enabled = false; + } + } + + /// + /// 리스폰 시 플레이어 다시 보임 + /// + [ClientRpc] + private void ShowPlayerClientRpc() + { + // CharacterController 활성화 + if (_controller != null) + { + _controller.enabled = true; + } + + // 모든 Renderer 활성화 + Renderer[] renderers = GetComponentsInChildren(); + foreach (Renderer renderer in renderers) + { + renderer.enabled = true; + } } private void HandleDeath() @@ -284,6 +392,9 @@ public class NetworkPlayerController : NetworkBehaviour, ITeamMember, IDamageabl { _networkAnimator.SetTrigger("Revive"); } + + // 플레이어 다시 보임 (이동 후 실행) + ShowPlayerClientRpc(); } [ClientRpc]