using MyCollections.Interfaces; using TMPro; using UnityEngine; using UnityEngine.UI; public class InventoryUI : MonoBehaviour, IReceiver<int, int> { [Header("Inventory Grid Settings: ")] [SerializeField] private GameObject UIslot; [SerializeField] private GameObject buttonOptions; [SerializeField] private GameObject inserPanel; [SerializeField] private float gridSpacingX, gridSpacingY; //the space between each tile of the matrix [SerializeField] private int columns = 5; // Number of columns in the inventory grid private GameManager gameManager; private GameObject currentButtonOptions = null; private GameObject currentInsertPanel = null; //UI Inventory Matrix Size GameObject[,] inventorySlots = null; void Awake() { gameManager = GameManager.Instance; } // Start is called before the first frame update void Start() { // Subscribe to inventory changes when the UI is active gameManager.inventory.InventoryChanged += UpdateUI; } private void UpdateUI() { if(inventorySlots != null) { ClearInventoryGrid(); CreatInventoryGrid(); } } private void CreatInventoryGrid() { // Get the inventory size from the GameManager int inventorySize = gameManager.inventorySize; // Calculate number of rows needed based on the inventory size and number of columns int rows = Mathf.CeilToInt((float)inventorySize / columns); // Initialize the 2D array based on rows and columns inventorySlots = new GameObject[rows, columns]; Debug.Log("Grid ROWS: " + rows); Debug.Log("Inventory SIZE: " + inventorySize); // Start drawing the inventory grid for (int row = 0; row < rows; row++) { for (int col = 0; col < columns; col++) { // Calculate the slot index (linear inventory index) int index = row * columns + col; // Ensure we don't create extra slots beyond the inventory size if (index >= inventorySize) break; // Calculate the position for each slot based on row, column, and spacing Vector3 position = new Vector3(col * gridSpacingX, -row * gridSpacingY, 0); // Instantiate the slot at the calculated position GameObject slot = Instantiate(UIslot, transform); Debug.Log("Slot: " + slot); Debug.Log("Transform: " + transform); // Set the slot position relative to the parent (Inventory UI panel) slot.GetComponent<RectTransform>().anchoredPosition = position; // Store the slot reference in the array inventorySlots[row, col] = slot; // Display the item in this slot DisplayItemUIInfo(index, slot); } } } private void ClearInventoryGrid() { // Ensure that the inventorySlots array exists if (inventorySlots != null) { // Iterate through all rows and columns, destroy the slot GameObjects for (int row = 0; row < inventorySlots.GetLength(0); row++) { for (int col = 0; col < inventorySlots.GetLength(1); col++) { if (inventorySlots[row, col] != null) { Destroy(inventorySlots[row, col]); } } } // Reset the inventorySlots array inventorySlots = null; } } private void ClearSlotOptions() { if (currentButtonOptions != null) Destroy(currentButtonOptions); } private void SetButtonListeners(GameObject slot, int index) { if (slot.TryGetComponent(out InventoryButton button)) { button.ButtonInit(this, index); } } public void DisplayButtonOptions(Vector3 position, int index) { if(currentButtonOptions != null) Destroy(currentButtonOptions); currentButtonOptions = Instantiate(buttonOptions, position, Quaternion.identity, gameObject.transform); Button[] buttons = currentButtonOptions.GetComponentsInChildren<Button>(); buttons[0].onClick.AddListener(delegate { SplitItemStack(index); Destroy(currentButtonOptions); }); buttons[1].onClick.AddListener(delegate { CreateInsertPanel(index); Destroy(currentButtonOptions); }); buttons[2].onClick.AddListener(delegate { //Discard the item DiscardItem(index); Destroy(currentButtonOptions); }); } private void CreateInsertPanel(int index) { InventorySlot slot = gameManager.inventory.GetSlot(index); if (slot == null) return; int amount = slot.Amount; if (currentInsertPanel != null) { Destroy(currentInsertPanel); } currentInsertPanel = Instantiate(inserPanel, gameObject.transform); if (currentInsertPanel.TryGetComponent(out AmountInserter inserter)) { inserter.Init(gameObject, amount, index); } } private void DisplayItemUIInfo(int index, GameObject slot) { // Get item from inventory list if (index < gameManager.inventory.Count) { InventorySlot inventorySlot = gameManager.inventory.InventorySlot(index); if (inventorySlot != null) { SetButtonListeners(slot, index); // Assign item sprite to the UI slot image Image[] images = slot.GetComponentsInChildren<Image>(); TextMeshProUGUI tmp = slot.GetComponentInChildren<TextMeshProUGUI>(); if (images != null) { foreach (Image image in images) { if (image.gameObject.transform.childCount == 0) { image.color = Color.white; image.sprite = inventorySlot.Item.ItemImage; tmp.text = inventorySlot.Amount > 1 ? inventorySlot.Amount.ToString() : string.Empty; } } //tmp.text = slot Debug.Log($"Changed Sprite at index: {index}"); return; } } Debug.LogWarning("Item is NUll"); } } private void Update() { if (Input.GetKeyDown(InputManager.GetKey(InputAction.SplitItemStack))) { //Activate } } private void OnEnable() { if (gameManager != null) { // Subscribe to inventory changes when the UI is active gameManager.inventory.InventoryChanged += UpdateUI; } CreatInventoryGrid(); } private void OnDisable() { ClearInventoryGrid(); gameManager.inventory.InventoryChanged -= UpdateUI; } public void SplitItemStack(int index) => gameManager.inventory.SplitSlot(index); public void OpenAmountInserter(int index) { //Instantiate the insert panel } public void DiscardItem(int index) => gameManager.inventory.RemoveItem(index); // public void Receive(int value, int index) => gameManager.inventory.DropItem(index, value); }