using System.Collections.Generic;
using System.Reflection;
using UnityEngine;
public class InventoryUI : MonoBehaviour
{
[Header("Data")]
[SerializeField] private InventoryData inventoryData;
[Header("UI (Canvas yang sudah ada)")]
[SerializeField] private InventorySlot slotPrefab;
[SerializeField] private Transform slotParent;
[Tooltip("Hapus slot placeholder yang sudah ada di slotParent saat mulai")]
[SerializeField] private bool clearExistingSlots = true;
[Header("Deteksi item")]
[SerializeField] private float scanInterval = 0.5f;
private readonly Dictionary<int, InventorySlot> slots = new Dictionary<int, InventorySlot>();
private readonly Dictionary<Item, int> trackedItems = new Dictionary<Item, int>();
private readonly List<Item> destroyedBuffer = new List<Item>();
private static readonly FieldInfo ItemIdField =
typeof(Item).GetField("itemId", BindingFlags.NonPublic | BindingFlags.Instance);
private float scanTimer;
private void Start()
{
if (clearExistingSlots)
{
foreach (Transform child in slotParent)
Destroy(child.gameObject);
}
ScanItems();
Refresh();
}
private void Update()
{
bool changed = false;
destroyedBuffer.Clear();
foreach (KeyValuePair<Item, int> pair in trackedItems)
{
if (pair.Key == null)
{
AddToInventory(pair.Value, 1);
destroyedBuffer.Add(pair.Key);
changed = true;
}
}
foreach (Item key in destroyedBuffer)
trackedItems.Remove(key);
if (changed) Refresh();
scanTimer += Time.deltaTime;
if (scanTimer >= scanInterval)
{
scanTimer = 0f;
ScanItems();
}
}
private void ScanItems()
{
Item[] items = FindObjectsByType<Item>(FindObjectsSortMode.None);
foreach (Item item in items)
{
if (trackedItems.ContainsKey(item)) continue;
int id = (int)ItemIdField.GetValue(item);
trackedItems.Add(item, id);
}
}
private void AddToInventory(int itemId, int amount)
{
ItemInventoryData data = inventoryData.ItemList.Find(i => i.ItemId == itemId);
if (data == null)
{
Debug.LogWarning($"ItemId {itemId} tidak ada di InventoryData.");
return;
}
data.ItemCount = Mathf.Max(0, data.ItemCount + amount);
}
public void Refresh()
{
int order = 0;
foreach (ItemInventoryData item in inventoryData.ItemList)
{
bool hasSlot = slots.TryGetValue(item.ItemId, out InventorySlot slot);
if (item.ItemCount <= 0)
{
if (hasSlot)
{
Destroy(slot.gameObject);
slots.Remove(item.ItemId);
}
continue;
}
if (!hasSlot)
{
slot = Instantiate(slotPrefab, slotParent);
slots.Add(item.ItemId, slot);
}
slot.ItemIcon.sprite = item.ItemIcon;
slot.ItemCount.text = item.ItemCount.ToString();
slot.transform.SetSiblingIndex(order++);
}
}
}
`
1 Like
A wall of code because??
2 Likes