How can i detect the first empty slot in an inventory and allocate an item on it instead

Im trying to make an inventory using LIst.
i have tried using find, or indexof, to find the first position on my list that would be empty, but it never finds the “null” on that slot, even when its empty.
Ive rewritten it so many different ways now, im just lost on it.

Is there a way to add an object to the earliest empty slot without adding more Capacity

You’re using a List<T>(); as though it was an array.

Arrays are oldskool: you cannot resize them once made, so if you take something out, you can put a null in to show it is empty.

Lists are newerskool: you can actually .Remove() or .RemoveAt() items and then they are just NOT in the list. Lists are like a deck of cards: you can just remove the card and it’s gone.

With a List, you just call .Add() to add more to it. That’s the entire point of a list.

^ ^ That’s another thing… don’t worry about capacity on a List… that’s the List’s problem, not yours. Let it grow, let it shrink, let it do its thing.

You probably want to pause at this point and review your C# collections fundamentals. I say this in all seriousness since an Inventory is by far one of the hardest most obtuse things to implement. It’s in a class of things that are so bafflingly abstract and complex and multi-layered that I actually keep a list of considerations around for it:

These things (inventory, shop systems, character customization, dialog tree systems, crafting, ability unlock systems, tech trees, etc) are fairly tricky hairy beasts, definitely deep in advanced coding territory.

The following applies to ALL types of code listed above, but for simplicity I will call it “inventory.”

Inventory code never lives “all by itself.” All inventory code is EXTREMELY tightly bound to prefabs and/or assets used to display and present and control the inventory. Problems and solutions must consider both code and assets as well as scene / prefab setup and connectivity.

If you contemplate late-delivery of content (product expansion packs, DLC, etc.), all of that has to be folded into the data source architecture from the beginning.

Inventories / shop systems / character selectors all contain elements of:

  • a database of items that you may possibly possess / equip
  • a database of the items that you actually possess / equip currently
  • perhaps another database of your “storage” area at home base?
  • persistence of this information to storage between game runs
  • presentation of the inventory to the user (may have to scale and grow, overlay parts, clothing, etc)
  • interaction with items in the inventory or on the character or in the home base storage area
  • interaction with the world to get items in and out
  • dependence on asset definition (images, etc.) for presentation
    → what it looks like lying around in the world? In a chest? On a shelf?
    → what it looks like in the inventory window itself?
    → what it looks like when worn by the player? Does it affect vision (binoculars, etc.)
    → what it looks like when used, destroyed, consumed?

Just the design choices of such a system can have a lot of complicating confounding issues, such as:

  • can you have multiple items? Is there a limit?
  • if there is an item limit, what is it? Total count? Weight? Size? Something else?
  • are those items shown individually or do they stack?
  • are coins / gems stacked but other stuff isn’t stacked?
  • do items have detailed data shown (durability, rarity, damage, etc.)?
  • can users combine items to make new items? How? Limits? Results? Messages of success/failure?
  • can users substantially modify items with other things like spells, gems, sockets, etc.?
  • does a worn-out item (shovel) become something else (like a stick) when the item wears out fully?
  • etc.

Your best bet is probably to write down exactly what you want feature-wise. It may be useful to get very familiar with an existing game so you have an actual example of each feature in action.

Once you have decided a baseline design, fully work through two or three different inventory tutorials on Youtube, perhaps even for the game example you have chosen above.

Breaking down a large problem such as inventory:

If you want to see most of the steps involved, make a “micro inventory” in your game, something whereby the player can have (or not have) a single item, and display that item in the UI, and let the user select that item and do things with it (take, drop, use, wear, eat, sell, buy, etc.).

Everything you learn doing that “micro inventory” of one item will apply when you have any larger more complex inventory, and it will give you a feel for what you are dealing with.

Breaking down large problems in general:

The moment you put an inventory system into place is also a fantastic time to consider your data lifetime and persistence. Create a load/save game and put the inventory data store into that load/save data area and begin loading/saving the game state every time you run / stop the game. Doing this early in the development cycle will make things much easier later on.

Various possible inventory data structures in Unity3D:

Using game objects doesn’t make for a workable inventory system. You want to define your own data structures in plain C# terms, giving you full control over how everything works. This will also be separate from your visual representation from the inventory itself.

Generally you are only using game objects for items that are live in the game world, or for UI if you happen to be using uGUI. Everything else should be pure data and scriptable objects.

But Kurt’s right, if you have a fixed size inventory then you want to use an array rather than list. You want to be using a custom object to represent each slot to, which than provide an API to tell whether any item is assigned to it or not.

Also side note, your for loop is also incorrect. They they typically are: for (int i = 0; i < myCollection.Count; i++). Your loop would only ever run once if .Capacity happens to equal zero.

I think, my mistake was the loop using for, i was using it wrong

added some stuff to it
apparently this works just fine :3

At the risk of incurring some wrath I’ll offer the opinion that “works just fine” isn’t a good measure of code effectiveness.

Pretty much every bug you have been affected by over the years on any application you have used that has experienced a crash, apparently worked fine.

As has been pointed out it is much better to post code “as code” rather than an image. That aside you will find almost nobody handling the adding of items to a collection quite this way. In the overall scheme of things that is a clue :slight_smile:

No need for you to change anything but consider alternatives as time permits.

what could be the alternative?

2 simple improvements would be the following:

  1. Use an Array instead of a List (ie GameObject[] instead of List<GameObject> )

  2. Make the array/list of type ItemScript instead of GameObject

So your code would be sometthing like this:

public ItemScript[] listInventory;

void Awake()
{
    // this creates an array that is the exact size of your inventory from the get go
    listInventory = new ItemScript[inventorySizeLimit];
}

Then you can skip the first and last portion of the code in your AllocateItem method, and can just keep the for loop. This will avoid running into future bugs too.

If you post the “rules” that govern your collection I believe the group could devise a class to meet your needs.

Fundamentally you choose between an array of a defined size or a list with a maximum capacity. If items can be removed from your inventory I would most probably go with the List. You can define a maximum capacity and simply not .add other elements if the count == the maximum capacity. The list will grow and shrink as needed it just won’t grow beyond your max.

You don’t null an array element but rather remove the element from the list. Your list contains no null elements everything in it is a valid inventory item.

I believe you would want to define your List as a class. You don’t interface with it as a list but rather as a class that knows the limits and rules. It can add, remove, clear, count, search and or anything else you might ask your Inventory object to do.

If you write it as a class you can instantiate one or more of them and use the class in other apps when you need this particular behavior. I’m going to guess that GameObject is a bit too broad a category for a list. I have to assume there are some properties that a game object must have to be considered an inventory item. That class or an interface should be what the list consists of.

Fundamentally your Inventory class provides a way to add new items and it checks the rules. It wouldn’t need to check if the count is currently zero or search for a null one. It adds it or rejects the request because the max items has been reached.

Toy with it a bit and you’ll see a reusable Inventory class take shape.

if .Capacity == 0, the for loop doesn’t even run. Did I miss something?