Ok, nice.
Well, you’re lacking the functionality of finding a specific item in your inventory.
Inventories should work in a doubly linked manner. I.e. if an item knows its slot, at the same time you should be able to check the slot and learn about the item.
Currently, I can see that your item knows about the slot, but your inventory doesn’t know anything about the items. You can only add new ones, or remove existing ones, and removing is also slot-agnostic.
Let’s do this differently.
using System;
using System.Collections.Generic;
public class Inventory {
List<Item> _items;
int _count;
public int ItemCount => _count;
int _limit;
public int Size => _limit;
public Inventory(int size) {
if(size <= 1) throw new ArgumentException();
_limit = size;
initItemList();
}
public Item this[int index] {
get => _items[index];
set => StoreAt(index, value);
}
private void initItemList() {
_items = new List<Item>(_limit);
for(int i = 0; i < _limit; i++) _items[i] = null;
_count = 0;
}
public bool IsEmptySlot(int index) => _items[index] == null;
public bool Contains(Item item) => _items.IndexOf(item) >= 0;
private int getEmptySlot() => _items.IndexOf(null);
public void Store(Item item) {
if(item == null) throw new ArgumentNullException();
if(_count == _limit) throw new InvalidOperationException("Limit has been reached");
int slot = getEmptySlot();
StoreAt(slot, item);
}
public bool TryStore(Item item) {
if(_count == _limit) return false;
int slot = getEmptySlot();
StoreAt(slot, item);
return true;
}
public void Empty(int index) => StoreAt(index, null);
public void StoreAt(int index, Item item) {
if(index < 0 || index >= _limit) throw new IndexOutOfRangeException();
bool wasEmpty = IsEmptySlot(index);
bool isEmpty = (item == null);
_items[index] = value;
if(wasEmpty && !isEmpty) _count++;
else if(!wasEmpty && isEmpty) _count--;
}
public Item Remove(Item item) {
if(item == null) throw new ArgumentNullException();
var slot = _items.IndexOf(item);
if(slot >= 0) { Empty(slot); return item; }
return null;
}
public bool RemoveAt(int index) {
bool wasEmpty = IsSlotEmpty(index);
Empty(index);
return !wasEmpty;
}
public void Clear() => initItemList();
public int FindFirstOf(Item item) {
if(item == null) throw new ArgumentNullException();
return _items.IndexOf(item);
}
public int[] FindMultiplesOf(Item item) {
if(item == null) throw new ArgumentNullException();
var result = new List<int>(_limit);
int index = -1;
while(index < _limit) {
index = _items.IndexOf(item, index + 1);
if(index < 0) break;
result.Add(index);
}
return result.ToArray();
}
}
Public Interface
Inventory(int size) - Creates new inventory with a set maximum of slots. Size must be greater than 0.
int ItemCount - Returns the count of used up slots in the inventory.
int Size - Returns the total count of slots in the inventory.
Item this[int index] - Sets or gets an item from the slot at index. May return null and may be set to null.
bool IsEmptySlot(int index) - Returns true if slot was empty (null), false otherwise.
bool Contains(Item item) - Returns true if the item exists in the inventory, false otherwise. Accepts null.
void Store(Item item) - Adds item to the first available empty slot. Throws error if no empty slots. Doesn’t accept null.
bool TryStore(Item item) - Adds item to the first available empty slot. Returns true on success, false otherwise. Doesn’t accept null.
void Empty(int index) - Empties slot at index.
void StoreAt(int index, Item item) - Sets an item into slot at index. Empties slot if null is used.
Item Remove(Item item) - Removes and returns an item if it existed in the inventory. Returns null if it wasn’t found. Doesn’t accept null for an item.
bool RemoveAt(int index) - Removes an item in slot at index. Returns true if slot wasn’t empty, false otherwise.
void Clear() - Clears the inventory of all items.
int FindFirstOf(Item item) - Returns the index of the first slot where item was found. Doesn’t accept null. Returns -1 if item was not found.
int[ ] FindMultiplesOf(Item item) - Returns an array of indices where instances of item were found. Doesn’t accept null. Returns empty array if nothing was found. Obsolete (see post #8)
This is only an extensive demo, basically.
It has an overwhelming amount of functionality just to showcase the possibilities and nominal features you’d expect from an inventory system. I don’t expect you to replace your code, but try to cherry pick what you need from this and adapt it to your code accordingly.
Tell me if you need a working example of how to use it. It should be simple enough.
Now, arguably there are better ways to do this, overall, especially if you expect your inventories to regularly have more than 30-ish slots, or if you have many of them, constantly in use. This should be enough, however, for a simple RPG style of game.
Please keep in mind I haven’t tested this at all, tell me if it’s buggy or something doesn’t work.
FindMultiplesOf might hang Unity in endless loop if I made a mistake. Save your work before trying it.
(edit: FindMultiplesOf has been replaced with a better method in the post #8, below)