using Unity.Netcode; using UnityEngine; namespace Northbound { /// /// 상호작용 대상 - 광산 (채광하기) /// public class Mine : NetworkBehaviour, IInteractable { [Header("Mine Settings")] public bool infiniteResources = false; // 무제한 자원 public int maxResources = 100; public int resourcesPerMining = 10; public float miningCooldown = 2f; public string resourceName = "광석"; [Header("Animation")] public string interactionAnimationTrigger = "Mining"; // 플레이어 애니메이션 트리거 [Header("Equipment")] public InteractionEquipmentData equipmentData = new InteractionEquipmentData { socketName = "RightHand", attachOnStart = true, detachOnEnd = true }; [Header("Visual")] public GameObject miningEffectPrefab; public Transform effectSpawnPoint; private NetworkVariable _currentResources = new NetworkVariable( 100, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server ); private float _lastMiningTime; public override void OnNetworkSpawn() { if (IsServer) { _currentResources.Value = maxResources; } } public bool CanInteract(ulong playerId) { // 무제한 자원이면 항상 채굴 가능 if (infiniteResources) return Time.time - _lastMiningTime >= miningCooldown; if (_currentResources.Value <= 0) return false; return Time.time - _lastMiningTime >= miningCooldown; } public void Interact(ulong playerId) { if (!CanInteract(playerId)) return; MineResourceServerRpc(playerId); } [ServerRpc(RequireOwnership = false)] private void MineResourceServerRpc(ulong playerId) { if (!CanInteract(playerId)) return; int minedAmount = resourcesPerMining; // 무제한이 아니면 자원 감소 if (!infiniteResources) { minedAmount = Mathf.Min(resourcesPerMining, _currentResources.Value); _currentResources.Value -= minedAmount; } _lastMiningTime = Time.time; Debug.Log($"플레이어 {playerId}가 {minedAmount} {resourceName}을(를) 채굴했습니다. " + (infiniteResources ? "(무제한)" : $"남은 자원: {_currentResources.Value}")); ShowMiningEffectClientRpc(); if (!infiniteResources && _currentResources.Value <= 0) { OnResourcesDepleted(); } } [ClientRpc] private void ShowMiningEffectClientRpc() { if (miningEffectPrefab != null && effectSpawnPoint != null) { GameObject effect = Instantiate(miningEffectPrefab, effectSpawnPoint.position, effectSpawnPoint.rotation); Destroy(effect, 2f); } } private void OnResourcesDepleted() { Debug.Log("광산이 고갈되었습니다!"); } public string GetInteractionPrompt() { if (infiniteResources) { return $"[E] {resourceName} 채굴 (무제한)"; } if (_currentResources.Value > 0) { return $"[E] {resourceName} 채굴 ({_currentResources.Value}/{maxResources})"; } return "고갈된 광산"; } public string GetInteractionAnimation() { return interactionAnimationTrigger; } public InteractionEquipmentData GetEquipmentData() { return equipmentData; } public Transform GetTransform() { return transform; } } }