using MyCollections.Interfaces; using TMPro; using UnityEngine; using UnityEngine.UI; public class DynamicInventoryUI : MonoBehaviour, IReceiver<int, int> { [Header("Inventory Grid Settings: ")] [SerializeField] private GameObject UIslot; [SerializeField] private GameObject buttonOptions; [SerializeField] private GameObject insertPanel; [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; [SerializeField] private InventoryManager inventoryManager; private Inventory inventory; //UI Inventory Matrix Size GameObject[,] inventorySlots = null; void Awake() { gameManager = GameManager.Instance; } // Start is called before the first frame update void Start() { inventoryManager = gameManager.PlayerController.GetComponentInChildren<InventoryManager>(); if (inventoryManager != null) { inventory = inventoryManager.Inventory; // Subscribe to inventory changes when the UI is active inventory.InventoryChanged += UpdateUI; CreateInventoryGrid(); } else { Debug.LogError($"Component not found: {nameof(InventoryManager)}"); } } private void UpdateUI() { if(inventorySlots != null) { ClearInventoryGrid(); CreateInventoryGrid(); } } private void CreateInventoryGrid() { // Get the inventory size from the player int inventorySize = inventory.Capacity; // 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]; // Calculate total width and height of the grid float gridWidth = columns * gridSpacingX; float gridHeight = rows * gridSpacingY; // Calculate the starting position for centering the grid Vector3 startPosition = new Vector3(-gridWidth / 2 + gridSpacingX / 2, gridHeight / 2 - gridSpacingY / 2, 0); // 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 = startPosition + new Vector3(col * gridSpacingX, -row * gridSpacingY, 0); // Instantiate the slot at the calculated position GameObject slot = Instantiate(UIslot, transform); 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(InventorySlot slot, int index) //{ // if (slot.gameObject.TryGetComponent(out InventoryButton button)) // { // slot // button.ButtonInit(slot, 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 = inventory.GetSlot(index); if (slot == null) return; int amount = slot.Amount; if (currentInsertPanel != null) { Destroy(currentInsertPanel); } currentInsertPanel = Instantiate(insertPanel, 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 < inventory.Count) { InventorySlot inventorySlot = 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 (inventory != null) { // Subscribe to inventory changes when the UI is active inventory.InventoryChanged += UpdateUI; CreateInventoryGrid(); } } private void OnDisable() { ClearInventoryGrid(); inventory.InventoryChanged -= UpdateUI; } public void SplitItemStack(int index) => inventory.SplitSlot(index); public void DiscardItem(int index) => inventory.RemoveItem(index); public void Receive(int value, int index) => inventoryManager.DropItem(index, value); }