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;
}