Home > OS >  How to fix inventory error in unity 2021.3.13f1
How to fix inventory error in unity 2021.3.13f1

Time:12-21

EDITED MORE SCRIPTS SHOWN! I'm making an inventory system from This YouTube Video and I can't seem to get it to work.

the error1: Assets\Scripts\InventoryScripts\InventorySystem.cs(31,33): error CS1579: foreach statement cannot operate on variables of type 'InventorySlot' because 'InventorySlot' does not contain a public instance or extension definition for 'GetEnumerator'

The error2:

Assets\Scripts\InventoryScripts\InventorySystem.cs(55,19): error CS0029: Cannot implicitly convert type 'System.Collections.Generic.List' to 'InventorySlot'

And my code:

using System.Collections;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using UnityEngine.Events;

[System.Serializable]
public class InventorySystem
{
    [SerializeField] private List<InventorySlot> inventorySlots;

    public int InventorySize => InventorySlots.Count;
    public List<InventorySlot> InventorySlots => inventorySlots;

    public UnityAction<InventorySlot> OnInventorySlotChanged;

    public InventorySystem(int size)
    {
        inventorySlots = new List<InventorySlot>(size);

        for(int i = 0; i < size; i  ) 
        {
            inventorySlots.Add(new InventorySlot());
        }
    }

    public bool AddToInventory(InventoryItemData itemToAdd, int amountToAdd)
    {
        if(ContainsItem(itemToAdd, out InventorySlot invSlot))
        {
            foreach(var slot in invSlot) 
            {
                if(slot.RoomLeftInStack(amountToAdd))
                {
                    slot.AddToStack(amountToAdd);
                    OnInventorySlotChanged?.Invoke(invSlot);
                    return true;
                }
            }
        }

        if(HasFreeSlot(out InventorySlot freeSlot))
        {
            freeSlot.UpdateInvSlot(itemToAdd, amountToAdd);
            OnInventorySlotChanged?.Invoke(freeSlot);
            return true;
        }
        
        return false;
    }

    public bool ContainsItem(InventoryItemData itemToAdd, out InventorySlot invSlot)
    {
        invSlot = InventorySlots.Where(i => i.ItemData == itemToAdd).ToList();
        return invSlot == null ? false : true;
    }

    public bool HasFreeSlot(out InventorySlot freeSlot)
    {
        freeSlot = InventorySlots.FirstOrDefault(i => i.ItemData == null);
        return freeSlot == null ? false : true;
    }
}

Holder script:

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

[System.Serializable]
public class InventoryHolder : MonoBehaviour
{
    [SerializeField] private int inventorySize;
    [SerializeField] protected InventorySystem inventorySystem;

    public InventorySystem InventorySystem => inventorySystem;

    public static UnityAction<InventorySystem> OnDynamicInventoryDisplayRequested;

    private void Awake()
    {
        inventorySystem = new InventorySystem(inventorySize);
    }
}

Slot Script:

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

[System.Serializable]
public class InventorySlot
{
    [SerializeField] private InventoryItemData itemData;
    [SerializeField] private int stackSize;

    public InventoryItemData ItemData => itemData;
    public int StackSize => stackSize;

    public InventorySlot(InventoryItemData source, int amount)
    {
        itemData = source;
        stackSize = amount;
    }

    public InventorySlot()
    {
        ClearSlot();
    }

    public bool RoomLeftInStack(int amountToAdd, out int amountRemaining)
    {
        amountRemaining = ItemData.maxStackSize - stackSize;
        return RoomLeftInStack(amountToAdd);
    }

    public bool RoomLeftInStack(int amountToAdd)
    {
        if(stackSize   amountToAdd <= itemData.maxStackSize) return true;
        else return false;
    }

    public void ClearSlot()
    {
        itemData = null;
        stackSize = -1;
    }

    public void UpdateInvSlot(InventoryItemData data, int amount)
    {
        itemData = data;
        stackSize = amount;
    }

    public void AddToStack(int amount)
    {
        stackSize  = amount;
    }

    public void RemoveFromStack(int amount)
    {
        stackSize -= amount;
    }
}

I'm just trying to remove these errors so I can test it.

CodePudding user response:

The Where method of the List class returns a List rather than a single InventorySlot object.

You can rewrite the function 'ContainsItem' like this:

public bool ContainsItem(InventoryItemData itemToAdd, out InventorySlot invSlot)
{
    invSlot = InventorySlots.FirstOrDefault(i => i.ItemData == itemToAdd);
    return invSlot == null ? false : true;
}
  • Related