자원 채집 및 반환 기능
텍스트 기능 및 폰트 추가
This commit is contained in:
190
Assets/Scripts/Resource.cs
Normal file
190
Assets/Scripts/Resource.cs
Normal file
@@ -0,0 +1,190 @@
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Northbound
|
||||
{
|
||||
/// <summary>
|
||||
/// 상호작용 대상 - 자원 채집
|
||||
/// </summary>
|
||||
public class Resource : NetworkBehaviour, IInteractable
|
||||
{
|
||||
[Header("Resource Settings")]
|
||||
public int maxResources = 100;
|
||||
public int resourcesPerGathering = 10;
|
||||
public float gatheringCooldown = 2f;
|
||||
public string resourceName = "광석";
|
||||
|
||||
[Header("Resource Recharge")]
|
||||
public float rechargeInterval = 5f; // 충전 주기 (초)
|
||||
public int rechargeAmount = 10; // 주기당 충전량
|
||||
|
||||
[Header("Animation")]
|
||||
public string interactionAnimationTrigger = "Mining"; // 플레이어 애니메이션 트리거
|
||||
|
||||
[Header("Equipment")]
|
||||
public InteractionEquipmentData equipmentData = new InteractionEquipmentData
|
||||
{
|
||||
socketName = "RightHand",
|
||||
attachOnStart = true,
|
||||
detachOnEnd = true
|
||||
};
|
||||
|
||||
[Header("Visual")]
|
||||
public GameObject gatheringEffectPrefab;
|
||||
public Transform effectSpawnPoint;
|
||||
|
||||
private NetworkVariable<int> _currentResources = new NetworkVariable<int>(
|
||||
0,
|
||||
NetworkVariableReadPermission.Everyone,
|
||||
NetworkVariableWritePermission.Server
|
||||
);
|
||||
|
||||
private float _lastGatheringTime;
|
||||
private float _lastRechargeTime;
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
if (IsServer)
|
||||
{
|
||||
_currentResources.Value = 0;
|
||||
_lastRechargeTime = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update()
|
||||
{
|
||||
if (!IsServer)
|
||||
return;
|
||||
|
||||
// 자원 충전 로직
|
||||
if (Time.time - _lastRechargeTime >= rechargeInterval)
|
||||
{
|
||||
if (_currentResources.Value < maxResources)
|
||||
{
|
||||
int rechargeAmountToAdd = Mathf.Min(rechargeAmount, maxResources - _currentResources.Value);
|
||||
_currentResources.Value += rechargeAmountToAdd;
|
||||
|
||||
Debug.Log($"{resourceName} {rechargeAmountToAdd} 충전됨. 현재: {_currentResources.Value}/{maxResources}");
|
||||
}
|
||||
|
||||
_lastRechargeTime = Time.time;
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanInteract(ulong playerId)
|
||||
{
|
||||
// 자원 노드에 자원이 없으면 상호작용 불가
|
||||
if (_currentResources.Value <= 0)
|
||||
return false;
|
||||
|
||||
// 쿨다운 확인
|
||||
if (Time.time - _lastGatheringTime < gatheringCooldown)
|
||||
return false;
|
||||
|
||||
// 플레이어 인벤토리 확인
|
||||
if (NetworkManager.Singleton != null &&
|
||||
NetworkManager.Singleton.ConnectedClients.TryGetValue(playerId, out var client))
|
||||
{
|
||||
if (client.PlayerObject != null)
|
||||
{
|
||||
var playerInventory = client.PlayerObject.GetComponent<PlayerResourceInventory>();
|
||||
if (playerInventory != null)
|
||||
{
|
||||
// 플레이어가 받을 수 있는 공간이 없으면 상호작용 불가
|
||||
if (playerInventory.GetAvailableSpace() <= 0)
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Interact(ulong playerId)
|
||||
{
|
||||
if (!CanInteract(playerId))
|
||||
return;
|
||||
|
||||
GatherResourceServerRpc(playerId);
|
||||
}
|
||||
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
private void GatherResourceServerRpc(ulong playerId)
|
||||
{
|
||||
if (!CanInteract(playerId))
|
||||
return;
|
||||
|
||||
// 플레이어의 인벤토리 확인
|
||||
var playerObject = NetworkManager.Singleton.ConnectedClients[playerId].PlayerObject;
|
||||
if (playerObject == null)
|
||||
return;
|
||||
|
||||
var playerInventory = playerObject.GetComponent<PlayerResourceInventory>();
|
||||
if (playerInventory == null)
|
||||
{
|
||||
Debug.LogWarning($"플레이어 {playerId}에게 PlayerResourceInventory 컴포넌트가 없습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 플레이어가 받을 수 있는 최대량 계산
|
||||
int playerAvailableSpace = playerInventory.GetAvailableSpace();
|
||||
|
||||
// 자원 노드가 줄 수 있는 양과 플레이어가 받을 수 있는 양 중 작은 값 선택
|
||||
int gatheredAmount = Mathf.Min(
|
||||
resourcesPerGathering,
|
||||
_currentResources.Value,
|
||||
playerAvailableSpace
|
||||
);
|
||||
|
||||
if (gatheredAmount <= 0)
|
||||
{
|
||||
Debug.Log($"플레이어 {playerId}의 인벤토리가 가득 찼습니다.");
|
||||
return;
|
||||
}
|
||||
|
||||
// 자원 차감
|
||||
_currentResources.Value -= gatheredAmount;
|
||||
_lastGatheringTime = Time.time;
|
||||
|
||||
// 플레이어에게 자원 추가
|
||||
playerInventory.AddResourceServerRpc(gatheredAmount);
|
||||
|
||||
Debug.Log($"플레이어 {playerId}가 {gatheredAmount} {resourceName}을(를) 채집했습니다. 남은 자원: {_currentResources.Value}");
|
||||
|
||||
ShowGatheringEffectClientRpc();
|
||||
}
|
||||
|
||||
[Rpc(SendTo.ClientsAndHost)]
|
||||
private void ShowGatheringEffectClientRpc()
|
||||
{
|
||||
if (gatheringEffectPrefab != null && effectSpawnPoint != null)
|
||||
{
|
||||
GameObject effect = Instantiate(gatheringEffectPrefab, effectSpawnPoint.position, effectSpawnPoint.rotation);
|
||||
Destroy(effect, 2f);
|
||||
}
|
||||
}
|
||||
|
||||
public string GetInteractionPrompt()
|
||||
{
|
||||
if (_currentResources.Value <= 0)
|
||||
return "자원 충전 중...";
|
||||
|
||||
return $"[E] {resourceName} 채집 ({_currentResources.Value}/{maxResources})";
|
||||
}
|
||||
|
||||
public string GetInteractionAnimation()
|
||||
{
|
||||
return interactionAnimationTrigger;
|
||||
}
|
||||
|
||||
public InteractionEquipmentData GetEquipmentData()
|
||||
{
|
||||
return equipmentData;
|
||||
}
|
||||
|
||||
public Transform GetTransform()
|
||||
{
|
||||
return transform;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user