using Unity.Netcode; using UnityEngine; namespace Northbound { /// /// 일회용 자원 아이템 - 상호작용 시 자원 획득 후 사라짐 /// public class ResourcePickup : NetworkBehaviour, IInteractable { [Header("Resource Settings")] public int resourceAmount = 50; // 획득할 자원량 public string resourceName = "보급품"; [Header("Animation")] public string interactionAnimationTrigger = "PickUp"; // 플레이어 애니메이션 트리거 [Header("Equipment")] public EquipmentData equipmentData = new EquipmentData { socketName = "", equipmentPrefab = null, attachOnStart = false, detachOnEnd = false }; [Header("Visual")] public GameObject pickupEffectPrefab; public Transform effectSpawnPoint; private bool _isCollected = false; public bool CanInteract(ulong playerId) { if (_isCollected) return false; var resourceManager = ServerResourceManager.Instance; if (resourceManager != null) { if (resourceManager.GetAvailableSpace(playerId) <= 0) return false; } return true; } public void Interact(ulong playerId) { if (!CanInteract(playerId)) return; CollectResourceServerRpc(playerId); } [Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)] private void CollectResourceServerRpc(ulong playerId) { if (!CanInteract(playerId)) return; if (_isCollected) return; _isCollected = true; var resourceManager = ServerResourceManager.Instance; if (resourceManager == null) { Debug.LogWarning("ServerResourceManager 인스턴스를 찾을 수 없습니다."); _isCollected = false; return; } int playerAvailableSpace = resourceManager.GetAvailableSpace(playerId); int collectedAmount = Mathf.Min(resourceAmount, playerAvailableSpace); if (collectedAmount <= 0) { _isCollected = false; return; } resourceManager.AddResource(playerId, collectedAmount); UpdatePlayerResourcesClientRpc(playerId); ShowPickupEffectClientRpc(); Invoke(nameof(DestroyPickup), 0.1f); } [Rpc(SendTo.ClientsAndHost)] private void UpdatePlayerResourcesClientRpc(ulong playerId) { var playerObject = NetworkManager.Singleton.ConnectedClients[playerId].PlayerObject; if (playerObject != null) { var playerInventory = playerObject.GetComponent(); if (playerInventory != null) { playerInventory.RequestResourceUpdateServerRpc(); } } } [Rpc(SendTo.ClientsAndHost)] private void ShowPickupEffectClientRpc() { if (pickupEffectPrefab != null) { Transform spawnPoint = effectSpawnPoint != null ? effectSpawnPoint : transform; GameObject effect = Instantiate(pickupEffectPrefab, spawnPoint.position, spawnPoint.rotation); Destroy(effect, 2f); } // 오브젝트를 즉시 비활성화하여 재상호작용 방지 gameObject.SetActive(false); } private void DestroyPickup() { if (IsServer && NetworkObject != null) { NetworkObject.Despawn(true); } } public string GetInteractionPrompt() { return $"[E] {resourceName} Get (+{resourceAmount})"; } public string GetInteractionAnimation() { return interactionAnimationTrigger; } public EquipmentData GetEquipmentData() { return equipmentData; } public Transform GetTransform() { return transform; } } }