Transfer items between inventories with a button

I’m trying to create a system where the player can transfer items (which are scriptable objects) to and from their inventory (which is pretty much just a list) to any chest’s inventory (which is also a list), by clicking a button which isn’t connected to either of those. I have an inventory script attached to the player object, and a chest inventory script attached to every chest object.

When the player clicks on a chest, a list of his inventory and of the chest’s inventory are displayed, each item having a button (which has a script containing the item’s name and the amount of said item). These buttons are on the canvas. My goal is to make it so the player can click on any of the buttons to transfer the corresponding item to the other inventory.

However, I can’t figure out how to link the items’ buttons to the right chest. I don’t know which script to attach to the buttons’ on click functions, and on which objects to put this script (player, chest or the button itself). I know how to connect the player’s inventory, since there is only one of those, but since there are going to be multiple chests I have no idea how to choose the correct one.

I already have a working function which adds any item to a chest’s inventory, which is in a script attached to the chests (not sure if it belongs there), but I can’t just put it in the on click functions, because each chest has a script like that. Is there a way for the button to detect the chest which has been interacted with, take its script and launch its Add function?

Here’s the player’s inventory script:

public class Inventory : MonoBehaviour
{
    [SerializeField] GameObject player;
    
    //The inventory's list, containing all the player's items
    public List<Item> inventoryList;

    //variables for the UI
    [SerializeField] GameObject slot;
    [SerializeField] InventoryUI inventoryUI;

    //Function which adds a given amount of a given item to the player's inventory (adds 1 by default)
    public void AddItem(Item _item, int _amount = 1)
    {
        //If the player already has the item in their inventory, or if the item is not stackable:
        if (!inventoryList.Contains(_item) || !_item.stackable)
        {
            //Adds the item to the list
            inventoryList.Add(_item);

            //Creates a new slot for the UI
            GameObject tempSlot = Instantiate(slot, gameObject.transform);
            tempSlot.GetComponent<Slot>().SetItem(_item);
            tempSlot.GetComponent<Slot>().IncreaseAmount(_amount);

            inventoryUI.AddItemToUI(_item, _amount);
        }
        else
        {
            //Goes through each slot until it finds the same item
            foreach (Transform child in gameObject.transform)
            {
                //If the items' names correspond:
                if (child.GetComponent<Slot>().item.name == _item.name)
                {
                    //Increment the item's amount by the given amount
                    child.GetComponent<Slot>().amount += _amount;
                    break;
                }
            }
            //Updates the UI
            inventoryUI.Increment(_item, _amount);
        }
        //Increases the player's weight by the item's weight
        weight += _item.weight;
    }

    //Function which removes a given amount of a given item from the player's inventory
    public void RemoveItem(Item _item, int _amount = 1)
    {
        //Goes through each slot
        foreach (Transform child in gameObject.transform)
        {
            //If it has found the item:
            if (child.GetComponent<Slot>().item.name == _item.name)
            {
                //If the new amount is exactly 0:
                if (child.GetComponent<Slot>().amount - _amount == 0)
                {
                    //destroy the slot, remove the item from the list and remove the item from the UI
                    Destroy(child.gameObject);
                    inventoryList.Remove(_item);
                    inventoryUI.RemoveItemFromUI(_item);
                }
                //If the new amount is greater than 0:
                else if (child.GetComponent<Slot>().amount - _amount > 0)
                {
                    //Simply update the item's amount
                    child.GetComponent<Slot>().amount -= _amount;
                    inventoryUI.Decrease(_item, _amount);
                }
                //If the new amount is under 0, do not do anything
                else
                {
                    Debug.LogWarning("Not enough items to remove!");
                }

                break;
            }
        }
    }
}

And here’s the chest inventory script:

public class ChestInventory : MonoBehaviour
{
    [SerializeField] GameObject slotsParent;

    [SerializeField] GameObject slot;

    public List<Item> chestList;
    public List<ChestItemButton> buttonsList;

    Inventory playerInventory;

    private void Start()
    {
        playerInventory = GameObject.FindGameObjectWithTag("Inventory").GetComponent<Inventory>();
    }

    //Function which adds item to the chest's inventory, this is the function I'm struggling to call
    public void AddItem(Item _item, int _amount)
    {
        //If the chest already contains the item, or if the item is not stackable:
        if (!chestList.Contains(_item) || !_item.stackable)
        {
            //Add the item to the chest's inventory's list
            chestList.Add(_item);

            //Create a slot for the UI
            GameObject tempSlot = Instantiate(slot, slotsParent.transform);
            tempSlot.GetComponent<Slot>().SetItem(_item);
            tempSlot.GetComponent<Slot>().IncreaseAmount(_amount);

            //Creates a ChestItemButton, which is used in another script to create a real button (this just holds some info)
            ChestItemButton chestButton = gameObject.AddComponent<ChestItemButton>();
            chestButton.itemName = _item.name;
            chestButton.amount = _amount;

            buttonsList.Add(chestButton);
        }
        else
        {
            //Goes through each slot until it finds the same item
            foreach (Transform child in slotsParent.transform)
            {
                //If the items' names correspond:
                if (child.GetComponent<Slot>().item.name == _item.name)
                {
                    //Increment the item's amount by the given amount
                    child.GetComponent<Slot>().amount += _amount;
                    break;
                }
            }

            //Goes through each chest item button in the buttons list
            foreach (ChestItemButton button in buttonsList)
            {
                //When it finds the corresponding item, increase its amount
                if (button.itemName == _item.name)
                {
                    button.amount += _amount;
                }
            }
        }
    }
}

Thanks!

Inventory systems can be very complicated and you might just have to rework yours, but I would suggest to first get a reference in the player’s inventory script, to the current opened chest.

Then attach the buttons to the player script and make a function in the player’s inventory script to transfer items.

I hope that helps!