2026-06-19 UI, UI로직
This commit is contained in:
185
Assets/My project/Inventory/Scripts/InventoryManager.cs
Normal file
185
Assets/My project/Inventory/Scripts/InventoryManager.cs
Normal file
@@ -0,0 +1,185 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Events;
|
||||
|
||||
[Serializable]
|
||||
public class InventoryItemStack
|
||||
{
|
||||
public InventoryItemType itemType;
|
||||
[Min(0)] public int count;
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
public class InventoryItemChangedEvent : UnityEvent<InventoryItemType, int>
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 실제 아이템 개수를 관리하는 중심 스크립트입니다.
|
||||
/// UI를 직접 수정하지 않고, 아이템 개수 변경 이벤트만 알려줍니다.
|
||||
/// </summary>
|
||||
[DisallowMultipleComponent]
|
||||
public class InventoryManager : MonoBehaviour
|
||||
{
|
||||
[Header("Initial Items")]
|
||||
[SerializeField] private List<InventoryItemStack> initialItems = new List<InventoryItemStack>();
|
||||
|
||||
[Header("Events")]
|
||||
public InventoryItemChangedEvent onItemCountChanged;
|
||||
public UnityEvent onInventoryChanged;
|
||||
|
||||
[Header("Debug")]
|
||||
[SerializeField] private bool showDebugLog = true;
|
||||
|
||||
private readonly Dictionary<InventoryItemType, int> itemCounts = new Dictionary<InventoryItemType, int>();
|
||||
|
||||
public event Action<InventoryItemType, int> ItemCountChanged;
|
||||
public event Action InventoryChanged;
|
||||
|
||||
private void Awake()
|
||||
{
|
||||
InitializeFromInspector();
|
||||
}
|
||||
|
||||
private void Start()
|
||||
{
|
||||
NotifyAllItemsChanged();
|
||||
}
|
||||
|
||||
private void InitializeFromInspector()
|
||||
{
|
||||
itemCounts.Clear();
|
||||
|
||||
foreach (InventoryItemType itemType in Enum.GetValues(typeof(InventoryItemType)))
|
||||
itemCounts[itemType] = 0;
|
||||
|
||||
for (int i = 0; i < initialItems.Count; i++)
|
||||
{
|
||||
InventoryItemStack stack = initialItems[i];
|
||||
if (stack == null)
|
||||
continue;
|
||||
|
||||
itemCounts[stack.itemType] = Mathf.Max(0, stack.count);
|
||||
}
|
||||
}
|
||||
|
||||
public void AddItem(InventoryItemType itemType)
|
||||
{
|
||||
AddItem(itemType, 1);
|
||||
}
|
||||
|
||||
public void AddItem(InventoryItemType itemType, int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
return;
|
||||
|
||||
int newCount = GetItemCount(itemType) + amount;
|
||||
SetItemCount(itemType, newCount);
|
||||
|
||||
if (showDebugLog)
|
||||
Debug.Log($"[InventoryManager] {itemType} +{amount} => {newCount}");
|
||||
}
|
||||
|
||||
public bool RemoveItem(InventoryItemType itemType)
|
||||
{
|
||||
return RemoveItem(itemType, 1);
|
||||
}
|
||||
|
||||
public bool RemoveItem(InventoryItemType itemType, int amount)
|
||||
{
|
||||
if (amount <= 0)
|
||||
return false;
|
||||
|
||||
int current = GetItemCount(itemType);
|
||||
|
||||
if (current < amount)
|
||||
{
|
||||
if (showDebugLog)
|
||||
Debug.LogWarning($"[InventoryManager] {itemType} 부족: 현재 {current}, 필요 {amount}");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
SetItemCount(itemType, current - amount);
|
||||
return true;
|
||||
}
|
||||
|
||||
public void SetItemCount(InventoryItemType itemType, int count)
|
||||
{
|
||||
int clampedCount = Mathf.Max(0, count);
|
||||
int previousCount = GetItemCount(itemType);
|
||||
|
||||
if (previousCount == clampedCount)
|
||||
return;
|
||||
|
||||
itemCounts[itemType] = clampedCount;
|
||||
NotifyItemChanged(itemType, clampedCount);
|
||||
}
|
||||
|
||||
public int GetItemCount(InventoryItemType itemType)
|
||||
{
|
||||
if (itemCounts.TryGetValue(itemType, out int count))
|
||||
return count;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
public bool HasItem(InventoryItemType itemType)
|
||||
{
|
||||
return GetItemCount(itemType) > 0;
|
||||
}
|
||||
|
||||
public bool HasItem(InventoryItemType itemType, int requiredAmount)
|
||||
{
|
||||
return GetItemCount(itemType) >= Mathf.Max(1, requiredAmount);
|
||||
}
|
||||
|
||||
public void ClearInventory()
|
||||
{
|
||||
foreach (InventoryItemType itemType in Enum.GetValues(typeof(InventoryItemType)))
|
||||
itemCounts[itemType] = 0;
|
||||
|
||||
NotifyAllItemsChanged();
|
||||
}
|
||||
|
||||
public IReadOnlyDictionary<InventoryItemType, int> GetAllItemCounts()
|
||||
{
|
||||
return itemCounts;
|
||||
}
|
||||
|
||||
private void NotifyItemChanged(InventoryItemType itemType, int count)
|
||||
{
|
||||
ItemCountChanged?.Invoke(itemType, count);
|
||||
InventoryChanged?.Invoke();
|
||||
|
||||
onItemCountChanged?.Invoke(itemType, count);
|
||||
onInventoryChanged?.Invoke();
|
||||
}
|
||||
|
||||
private void NotifyAllItemsChanged()
|
||||
{
|
||||
foreach (KeyValuePair<InventoryItemType, int> pair in itemCounts)
|
||||
{
|
||||
ItemCountChanged?.Invoke(pair.Key, pair.Value);
|
||||
onItemCountChanged?.Invoke(pair.Key, pair.Value);
|
||||
}
|
||||
|
||||
InventoryChanged?.Invoke();
|
||||
onInventoryChanged?.Invoke();
|
||||
}
|
||||
|
||||
#if UNITY_EDITOR
|
||||
private void OnValidate()
|
||||
{
|
||||
if (initialItems == null)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < initialItems.Count; i++)
|
||||
{
|
||||
if (initialItems[i] != null)
|
||||
initialItems[i].count = Mathf.Max(0, initialItems[i].count);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
Reference in New Issue
Block a user