인벤토리/퀵슬롯 시스템 개발
This commit is contained in:
@@ -1,23 +1,89 @@
|
||||
using Unity.Netcode;
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
public class PlayerInventory : NetworkBehaviour
|
||||
{
|
||||
// 아이템 이름과 개수를 저장
|
||||
private Dictionary<string, int> items = new Dictionary<string, int>();
|
||||
[Header("Inventory Settings")]
|
||||
[Range(1, 10)] // 인스펙터에서 슬라이더로 조절 가능
|
||||
public int slotCount = 5;
|
||||
public float maxWeight = 50f;
|
||||
|
||||
public void AddItem(ItemData data)
|
||||
public struct InventorySlot : INetworkSerializable, IEquatable<InventorySlot>
|
||||
{
|
||||
if (!IsServer) return;
|
||||
public int ItemID; // string에서 int로 변경
|
||||
public int Amount;
|
||||
|
||||
if (items.ContainsKey(data.itemName))
|
||||
items[data.itemName]++;
|
||||
else
|
||||
items.Add(data.itemName, 1);
|
||||
public void NetworkSerialize<T>(BufferSerializer<T> serializer) where T : IReaderWriter
|
||||
{
|
||||
serializer.SerializeValue(ref ItemID);
|
||||
serializer.SerializeValue(ref Amount);
|
||||
}
|
||||
|
||||
Debug.Log($"[Inventory] {data.itemName} 획득! (현재: {items[data.itemName]}개)");
|
||||
public bool Equals(InventorySlot other) => ItemID == other.ItemID && Amount == other.Amount;
|
||||
}
|
||||
|
||||
// 여기서 클라이언트 UI를 갱신하는 ClientRpc를 호출할 수 있습니다.
|
||||
[Header("References")]
|
||||
[SerializeField] private ItemDatabase database;
|
||||
|
||||
public NetworkList<InventorySlot> Slots;
|
||||
// 무게 정보는 서버에서만 쓰고 나머지는 읽기만 가능 (네트워크 보안)
|
||||
private NetworkVariable<float> _currentWeight = new NetworkVariable<float>(0f, NetworkVariableReadPermission.Everyone, NetworkVariableWritePermission.Server);
|
||||
|
||||
public float CurrentWeight => _currentWeight.Value;
|
||||
|
||||
void Awake()
|
||||
{
|
||||
Slots = new NetworkList<InventorySlot>();
|
||||
}
|
||||
|
||||
public override void OnNetworkSpawn()
|
||||
{
|
||||
// 서버에서만 슬롯 초기화
|
||||
if (IsServer && Slots.Count == 0)
|
||||
{
|
||||
// 설정된 slotCount만큼 데이터 슬롯 생성
|
||||
for (int i = 0; i < slotCount; i++)
|
||||
Slots.Add(new InventorySlot { ItemID = -1, Amount = 0 });
|
||||
}
|
||||
|
||||
// 로컬 플레이어라면 UI 연결
|
||||
if (IsOwner)
|
||||
{
|
||||
QuickslotUI ui = FindFirstObjectByType<QuickslotUI>();
|
||||
if (ui != null) ui.BindInventory(this);
|
||||
}
|
||||
}
|
||||
|
||||
// PlayerInventory.cs 내의 AddItemRpc 예시
|
||||
[Rpc(SendTo.Server, InvokePermission = RpcInvokePermission.Everyone)]
|
||||
public void AddItemRpc(int itemID, int amount)
|
||||
{
|
||||
// 이제 필드 변수 없이 바로 접근 가능!
|
||||
ItemData data = ItemDatabase.Instance.GetItemByID(itemID);
|
||||
if (data == null) return;
|
||||
|
||||
float addedWeight = data.weight * amount;
|
||||
bool added = false;
|
||||
|
||||
for (int i = 0; i < Slots.Count; i++)
|
||||
{
|
||||
// 기존에 같은 아이템이 있거나(-1은 빈 슬롯을 의미) 빈 슬롯인 경우
|
||||
if (Slots[i].ItemID == itemID || Slots[i].ItemID == -1)
|
||||
{
|
||||
Slots[i] = new InventorySlot
|
||||
{
|
||||
ItemID = itemID,
|
||||
Amount = Slots[i].Amount + amount
|
||||
};
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (added)
|
||||
{
|
||||
_currentWeight.Value += addedWeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user