[Help] I don't know how to create a stacking system for my inventory!

I want to create something to stack my items, but I don’t know how. I want to have a maximum of how much it can stack and than use a new inventoryslot.
This is my code:


Scriptable Item code:

using UnityEngine;

[CreateAssetMenu(fileName = "new item", menuName = "Inventory/Item")]
public class Item : ScriptableObject {
    
    new public string name = "new item";
    public Sprite icon = null;
    public GameObject objectToDrop;
    public string description;
    public int maxStackSize;
    public bool isStackable;

}

The InventorySlot script:

using UnityEngine;
using UnityEngine.UI;
using System.Collections.Generic;
using System.Collections;
using TMPro;

public class InventorySlot : MonoBehaviour {

public Image icon, icon2;
public Button removeButton;
public Transform player;
public GameObject uiDescription, sellItem, nextStage;
public TextMeshProUGUI textDescription, itemNameText;

private Item item;

private void Start()
{
    icon.enabled = false;
    textDescription = textDescription.GetComponent<TextMeshProUGUI>();
    itemNameText = itemNameText.GetComponent<TextMeshProUGUI>();

}

private void Update()
{
    if (icon.sprite != null)
    {
        icon.enabled = true;
    }
    else {
        icon.enabled = false;
    }
}

public void AddItem(Item newItem) {
    item = newItem;
    icon.sprite = item.icon;
    icon.enabled = true;
    removeButton.GetComponent<Image>().enabled = true;
}

public void ClearSlot() {
    icon.sprite = null;
    icon.enabled = false;
    removeButton.GetComponent<Image>().enabled = false;
}

public void OnRemoveButton() {
    PlayerInventory.instance.Remove(item);
    Instantiate(item.objectToDrop, player.transform.position, Quaternion.identity);
    uiDescription.SetActive(false);
    item = null;
}

public void UIOpenButton() {
    if (item != null) {
        uiDescription.SetActive(!uiDescription.activeSelf);
        icon2.sprite = item.icon;

        textDescription.text = item.description;
        itemNameText.text = item.name;
    }
}
}

The PlayerInventory script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerInventory : MonoBehaviour {

public GameObject inventory, escapeMenu, playerUIStats, playerSelflookInventory;
public int inventorySpace;
public List<Item> items = new List<Item>();
public bool inventoryAcces;

private bool inventoryClose;

#region Singleton
public static PlayerInventory instance;

private void Awake()
{
    if (instance != null) {
        Debug.LogWarning("More then one inventory");
        return;
    }
    instance = this;
}

#endregion

public delegate void OnItemChanged();
public OnItemChanged onItemChangedCallBack;

private void Start()
{
    inventoryAcces = true;
}

// Update is called once per frame
void Update () {
    KeyInput();
    Inventory();
}

#region Inventory- &EscapeClose/Open

public bool Add(Item item) {
    if (items.Count >= inventorySpace) {
        Debug.Log("not enough space to pickup");
        return false;
    }
    items.Add(item);

    if (onItemChangedCallBack != null)
    {
        onItemChangedCallBack.Invoke();
    }
    return true;
}

public void Remove(Item item) {
    items.Remove(item);
    if (onItemChangedCallBack != null)
    {
        onItemChangedCallBack.Invoke();
    }
}
}

(I have deleted some code in the PlayerInventory script about opening and closing the inventory, because I think it isn’t needed for this problem. If you need to see it please say it).


The inventoryUI updating script:

 using System.Collections;
 using System.Collections.Generic;
 using UnityEngine;

public class InventoryUI : MonoBehaviour {

public Transform itemsParent;

private PlayerInventory inventory;
private InventorySlot[] slots;

void Start () {
    inventory = PlayerInventory.instance;
    inventory.onItemChangedCallBack += UpdateUI;

    slots = itemsParent.GetComponentsInChildren<InventorySlot>();
}

private void UpdateUI()
{
    for (int i = 0; i < slots.Length; i++)
    {
        if (i < inventory.items.Count)
        {
            slots_.AddItem(inventory.items*);*_

}
else
{
slots*.ClearSlot();*
}
}
}
}
----------
If someone knows how to create the stacking system please let me know. I’m struggeling with it for almost a week now.
----------
(I also have a bug with dropping a item and then pick it up, but when I pick it up it changed to a different item. I think I can do that by my own, but I have found the bug just a hour ago. It’s not my main question, but if you know what is causing that bug please let me know).
----------
Thanks for helping.

I don’t have a list of different items only a list of all items in the inventory, the probleem I have is that I want to acces the list of all items and when a item is added to see if a item of the same name is already in the inventory. If that’s the case I want to not add it in a different slot, but in the slot where the item of the same name is stored. But if the max stack size is reached to use a new slot. Do you know how to achieve that?

Here is an uncompiled/untested (may contain errors) example. I only filled in code for the AddItem function and will leave the RemoveItem, and a couple other potentially useful functions, for you to complete. But I think the AddItem function example should give you an idea on how to do those.

class InventorySlot
{
    public string nameOfTypeOfItemStored;
    public int inventoryCount = 0;
}

class Inventory
{
    public const int numberOfInventorySlots=20;
    public const int maxInventoryCountPerSlot = 100; // max 100 per slot
    public InventorySlot[] allInventorySlots = new InventorySlot[numberOfInventorySlots];  ///creates 20 slots in each inventory

    //this function returns the number of items successfully stored in inventory.  If not equal to the parameter quantity-  the function failed to store all them.
    public int AddItem(string itemName, int quantity = 1) 
    {
        int originalQuantity = quantity;
        for (int i = 0; i < numberOfInventorySlots; i++)
        {
            if (allInventorySlots *!= null) //is there anything in this inventory slot?*

{
if (allInventorySlots*.nameOfTypeOfItemStored == itemName)*
{
int freeSpace = maxInventoryCountPerSlot - allInventorySlots*.inventoryCount;*
if (freeSpace > quantity)
{
allInventorySlots*.inventoryCount += quantity;*
return originalQuantity; // all items stored- done
}
else// not enough free space in this slot to store all of the quantity
{
quantity = quantity - freespace;
allInventorySlots*.inventoryCount += freespace;*
//now we continue looping with the unstored portion in “quantity”
}
}
}
}// end for loop

//if we reach here, we have not yet stored the full quanity of items, and will need to create a new slot

for (int i = 0; i < numberOfInventorySlots; i++)
{
if (allInventorySlots == null || allInventorySlots*.inventoryCount==0)*
{
allInventorySlots = new InventorySlot();
allInventorySlots*.nameOfTypeOfItemStored = itemName;*
if (quantity <= maxInventoryCountPerSlot)
{
allInventorySlots*.inventoryCount = quantity;*
return originalQuantity;
}
else
{
allInventorySlots*.inventoryCount = maxInventoryCountPerSlot;*
quantity -= maxInventoryCountPerSlot;
}
}
}
//if we reach here, we have not yet stored the full quanity of items, and there are not enough slots to do so
return originalQuantity - quantity;
}
public int RemoveItems(string itemName, int quantity = 1)
{…}
public int[] SlotsContainingItem(string itemName)
{…}
public int TotalNumberOfItemsInInventory(string itemName)
{…}

}

Done this before, but with database instead.
The first thing you want is to have a stack/list/array somewhere, lets say you can have it in the UI item itself.

List<Item> stack

Second thing you want to have are methods to add, remove and access the item from that stack, what I do is always interact with them from the top down. Since I do multiple selection within the stack, not only I fetch the last one, but a range from it.

Finally you want you want yo have a numeric display on your InventorySlot class which will simply display the item.count value, updated whenever add/remove are called.

I got the stacking system working only thing that doesn’t work is that the itemcount per stack does not move with the item if it’s set to a new itemslot. If you know how to do that please let me know. There is a UpdateUI script which handles the place items are stored in there item slot and which place a item in a new itemslot if a item
is dropped. I think I have to write the code for moving itemscount with their item should be added there, I only don’t know how.