Bug When drop item with Gamepad

Hi, I have a strange bug.
If a drop the first Item from the inventory it will drops all items.
And for example I have 6 items in the inventory and I drop the fourth, then it drops the first and second.
The script belows is on the InventorySlot prefab attached.

public class ChangeSlotUI : MonoBehaviour
    {
        private InventorySlotUI inventorySlotUI;
        private UserInput userInput;
        

        private float canInput = -1f;
        private float generalInputRate = 2f;


        private void Awake() 
        {
            userInput = new UserInput();

            //userInput.Inventory.Drop.performed += drop => DropItem();
            //userInput.Inventory.Equip.performed += equip => EquipItem();
        }

        private void OnEnable()
        {
            userInput.Enable();
        }

        private void OnDisable()
        {
            userInput.Disable();
        }

        private void Start()
        {
            inventorySlotUI = GetComponent<InventorySlotUI>();
        }

        private void Update() 
        {
            DropItem();
            EquipItem();    
        }

        private void DropItem()
        {
            //float drop = userInput.Inventory.Drop.ReadValue<float>();
            if (userInput.Inventory.Drop.triggered && inventorySlotUI.GetItem() != null && Time.time > canInput)
            {
                canInput = Time.time + generalInputRate;
                Debug.Log("You have droped the item");
                var target = GameObject.FindGameObjectWithTag("InventoryCanvas").GetComponent<InventoryDropTarget>();
                target.AddItems(inventorySlotUI.GetItem(), inventorySlotUI.GetNumber());
                inventorySlotUI.RemoveItems(inventorySlotUI.GetNumber());
            }            
        }

        private void EquipItem()
        {
            float equip = userInput.Inventory.Equip.ReadValue<float>();
            if (equip == 1 && inventorySlotUI.GetItem() != null && Time.time > canInput)
            {
                canInput = Time.time + generalInputRate;
                Debug.Log("The Item is equiped");
            }
        }
}

If this script is active on each of the Inventory Slots, how does slot 6 know that you mean to drop slot 4? How does slot 1 and 2 know that you mean to drop slot 4? They are all using the same trigger.

1 Like

Ohh my god!! Yeah that’s really worse.
I’ve changed the following:
I add on the InventorySlotUI script the interface ISelectHandler and add some code block (at the end of script).

namespace GameDevTV.UI.Inventories
{
    public class InventorySlotUI : MonoBehaviour, IItemHolder, IDragContainer<InventoryItem>, ISelectHandler
    {
        // CONFIG DATA
        [SerializeField] InventoryItemIcon icon = null;

        // STATE
        int index;
        InventoryItem item;
        Inventory inventory;

        // MY WRITTEN STATE
        ChangeSlotUI changeSlotUI;

        // PUBLIC

        public void Setup(Inventory inventory, int index)
        {
            this.inventory = inventory;
            this.index = index;
            icon.SetItem(inventory.GetItemInSlot(index), inventory.GetNumberInSlot(index));
        }

        public int MaxAcceptable(InventoryItem item)
        {
            if (inventory.HasSpaceFor(item))
            {
                return int.MaxValue;
            }
            return 0;
        }

        public void AddItems(InventoryItem item, int number)
        {
            inventory.AddItemToSlot(index, item, number);
        }

        public InventoryItem GetItem()
        {
            return inventory.GetItemInSlot(index);
        }

        public int GetNumber()
        {
            return inventory.GetNumberInSlot(index);
        }

        public void RemoveItems(int number)
        {
            inventory.RemoveFromSlot(index, number);
        }

        // MY CODE
        public void OnSelect(BaseEventData eventData)
        {
            Debug.Log("Slot number: " + this.index + " is selected. Yeah!!!");
            changeSlotUI = GetComponentInParent<ChangeSlotUI>();
            changeSlotUI.SetSelectedItem(inventory.GetItemInSlot(this.index), this.index);
        }
    }
}

Then I’ve changed my script ChangeSlotUI and attached it now on the gameobject InventoryItems where is the parent of all InventorySlot prefabs.
image

namespace BS.UI.Inventories
{
    public class ChangeSlotUI : MonoBehaviour
    {
        private Inventory playerInventory;
        private InventoryUI inventoryUI;
        private InventoryItem selectedItem;
        private UserInput userInput;
        private UIMenu uIMenu;

        private int slotIndex;
        private float canInput = -1f;
        private float generalInputRate = 2f;

        private void Awake() 
        {
            userInput = new UserInput();

            userInput.Inventory.Drop.performed += drop => DropItem();
            userInput.Inventory.Equip.performed += equip => EquipItem();
        }

        private void OnEnable()
        {
            userInput.Inventory.Enable();
        }

        private void OnDisable()
        {
            userInput.Inventory.Disable();
        }

        private void Start()
        {
            inventoryUI = GetComponent<InventoryUI>();
            playerInventory = GameObject.FindGameObjectWithTag("Player").GetComponent<Inventory>();            
            uIMenu = GameObject.FindGameObjectWithTag("UIManager").GetComponent<UIMenu>();
        }
       
        private void DropItem()
        {            
            if (selectedItem != null && uIMenu.GetInventoryIsOpen() && Time.time > canInput)
            {
                canInput = Time.time + generalInputRate;                
                
                var target = GameObject.FindGameObjectWithTag("InventoryCanvas").GetComponent<InventoryDropTarget>();
                target.AddItems(selectedItem, slotIndex);
                playerInventory.RemoveFromSlot(slotIndex, 1);
                Debug.Log("You have droped the item");                
            }            
        }

        private void EquipItem()
        {            
            if (selectedItem != null && uIMenu.GetInventoryIsOpen() && Time.time > canInput)
            {
                canInput = Time.time + generalInputRate;
                Debug.Log("The Item is equiped");                
            }
        }

        public void SetSelectedItem(InventoryItem inventoryItem, int index)
        {
            selectedItem = inventoryItem;
            slotIndex = index;
        }        
    }
}

Maybe it’s not the best solution :slight_smile: but it work now.
Brian, thanks so mutch for your hint.

1 Like

Well done!

Thanks :sunglasses:

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.

Privacy & Terms