Files
BookRPG/Assets/Scripts/InventoryUI.cs

177 lines
5.6 KiB
C#
Raw Permalink Normal View History

using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class InventoryUI : MonoBehaviour
{
[SerializeField] private Transform inventoryContent; // Panel > ScrollView > Viewport > Content
[SerializeField] private GameObject inventoryItemPrefab;
[SerializeField] private Transform weaponSlot;
[SerializeField] private Transform armorSlot;
[SerializeField] private Inventory inventory;
private Canvas canvas;
private GameObject contextMenu;
private InventoryItemUI selectedItem;
void Start()
{
canvas = GetComponentInParent<Canvas>();
if (inventory == null)
inventory = FindObjectOfType<Inventory>();
RefreshInventoryUI();
}
public void RefreshInventoryUI()
{
// Clear existing items
foreach (Transform child in inventoryContent)
Destroy(child.gameObject);
// Populate inventory slots
var slots = inventory.GetInventorySlots();
foreach (var slot in slots)
{
CreateInventoryItemUI(slot.item, slot.quantity);
}
// Update equipment slots
UpdateEquipmentSlots();
}
private void CreateInventoryItemUI(Item item, int quantity)
{
GameObject itemUI = Instantiate(inventoryItemPrefab, inventoryContent);
InventoryItemUI itemScript = itemUI.GetComponent<InventoryItemUI>();
itemScript.Initialize(item, quantity, this);
}
private void UpdateEquipmentSlots()
{
Item equippedWeapon = inventory.GetEquippedItem(Item.ItemType.Weapon);
Item equippedArmor = inventory.GetEquippedItem(Item.ItemType.Armor);
UpdateEquipSlot(weaponSlot, equippedWeapon);
UpdateEquipSlot(armorSlot, equippedArmor);
}
private void UpdateEquipSlot(Transform slot, Item item)
{
Image slotImage = slot.GetComponent<Image>();
if (item != null && item.itemIcon != null)
{
slotImage.sprite = item.itemIcon;
slotImage.color = Color.white;
}
else
{
slotImage.sprite = null;
slotImage.color = new Color(1, 1, 1, 0.3f);
}
}
public void ShowContextMenu(InventoryItemUI itemUI, Item item)
{
selectedItem = itemUI;
if (contextMenu != null)
Destroy(contextMenu);
contextMenu = new GameObject("ContextMenu");
contextMenu.transform.SetParent(canvas.transform, false);
VerticalLayoutGroup layout = contextMenu.AddComponent<VerticalLayoutGroup>();
layout.childForceExpandHeight = false;
layout.childForceExpandWidth = false;
layout.spacing = 2;
LayoutElement layoutElement = contextMenu.AddComponent<LayoutElement>();
layoutElement.preferredWidth = 120;
layoutElement.preferredHeight = 140;
RectTransform rectTransform = contextMenu.GetComponent<RectTransform>();
rectTransform.sizeDelta = new Vector2(120, 140);
rectTransform.anchoredPosition = Input.mousePosition / canvas.scaleFactor;
Image bgImage = contextMenu.AddComponent<Image>();
bgImage.color = new Color(0.1f, 0.1f, 0.1f, 0.9f);
// Add menu options based on item type
if (item.itemType == Item.ItemType.Weapon || item.itemType == Item.ItemType.Armor)
AddMenuButton(contextMenu, "Equip", () => OnEquip(item));
if (item.itemType == Item.ItemType.Consumable)
AddMenuButton(contextMenu, "Use", () => OnUse(item));
AddMenuButton(contextMenu, "Info", () => OnInfo(item));
AddMenuButton(contextMenu, "Drop", () => OnDrop(item));
// Close menu on click elsewhere
StartCoroutine(WaitForClickOutside());
}
private void AddMenuButton(GameObject parent, string label, UnityEngine.Events.UnityAction onClick)
{
GameObject buttonObj = new GameObject(label);
buttonObj.transform.SetParent(parent.transform, false);
Button button = buttonObj.AddComponent<Button>();
Text text = buttonObj.AddComponent<Text>();
text.text = label;
text.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
text.alignment = TextAnchor.MiddleCenter;
text.color = Color.white;
text.fontSize = 12;
RectTransform rect = buttonObj.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(100, 30);
LayoutElement layoutElement = buttonObj.AddComponent<LayoutElement>();
layoutElement.preferredWidth = 100;
layoutElement.preferredHeight = 30;
button.onClick.AddListener(onClick);
button.onClick.AddListener(() => Destroy(contextMenu));
}
private void OnEquip(Item item)
{
inventory.EquipItem(item.itemName);
RefreshInventoryUI();
}
private void OnUse(Item item)
{
inventory.UseItem(item.itemName);
RefreshInventoryUI();
}
private void OnInfo(Item item)
{
Debug.Log($"--- {item.itemName} ---\n{item.itemDescription}\nType: {item.itemType}\nID: {item.itemID}");
// TODO: Show item info panel
}
private void OnDrop(Item item)
{
inventory.DropItem(item.itemName, 1);
RefreshInventoryUI();
}
private System.Collections.IEnumerator WaitForClickOutside()
{
while (true)
{
if (Input.GetMouseButtonDown(0) && contextMenu != null)
{
// Destroy menu when clicking anywhere (simplified approach)
Destroy(contextMenu);
yield break;
}
yield return null;
}
}
}