Question on performance regarding inventory system on a third world adventure game.

I’m working on a third person adventure game just as a fun project.

I have the following question regarding the best way of implementing an inventory system.

Say the main player can have other “GameObjects”, for example a crafting table, in his inventory.

The player can then place the crafting table as an actual GameObject inside the world. the crafting table itself has an inventory as well as some functions.

The question is as follows:

Is it better to implement such inventory system as a GameObject list. Where actual GameObjects can be stored, with all their information, state, etc. ?

or

Is it more efficient to implement such inventory system as, for example, a string list. where a new object is created in game based on the strings stored in the inventory?

In simpler terms,

Say the player collects 1000 crafting tables.

Is it more efficient to instantiate those 1000 tables as GameObjects directly in the inventory and then manipulate them as necessary.

or

Is it more efficient to keep an abstract reference to the objects (for example as a string) inside the inventory and then instantiate each one individually as necessary.

In even simpler terms,

How does a GameObject list’s performance scale up as the items become more numerous/complex ?

and

Is it overall cheaper to instantiate 1000 objects at once, or instantiate 1 object a 1000 different times ?

I would love to hear some opinions.

A list of game objects is a list of references to game objects…

As for putting the ‘Game objects’ in your inventory; in the context it seems that you’re asking, I wouldn’t understand how that works. If the ‘object’ is in the 3d world, wouldn’t you want a 2d representation of it for your inventory? Unless your idea for inventory is drastically different than what I’m used to…

Then, if they can be spawned, sure… put it in the world, with its “inventory” that it has also… or what not.

As for instantiating 1 vs 1000 or what not… It may be a matter of what you think is common place in your game.
Are they going to have 1000 crafting tables at once in the world? (why?) :slight_smile:
You could use an object pool that grows on demand, perhaps with a small starting # that you create and hide at the start, if you think this will be a common item in your game…

Just my 2 cents.

In a semi-related subject, one of the biggest problems that I have with Inventory Pro is its use of the UI representation of inventory objects as the object container itself, and all of the logic for the “inventory” interpreting how things are set up in the UI. You drag an object’s 2D sprite around the UI, it physically moves the location that the object exists in the scene to be parented under a new UI element (inventory slot), and the inventory system’s accessors simply iterate through each of the UI elements to their child objects and see which items are in which slots, etc…

This feels extremely backwards to me- I’ve never liked it.

I’m not bringing this up as a criticism of Inventory Pro as an asset though- it was EXTREMELY useful in figuring out how I wanted my own custom inventory system to work (and not work), and the editor back-end for storing static item data in ScriptableObjects is top-notch. I cannibalized it, and expanded on it, and I honestly think it’s one of the single most valuable assets I’ve purchased- it’s just ironic that I threw away the actual inventory system from it. The point is, there are several ways that you can make an inventory system, and each has their own pros and cons. I’m uncertain exactly what the pros are to Inventory Pro’s style here of abusing the UI system for logical containers, but it’s definitely an option, and if you’re leaning in that direction I highly recommend picking the asset up.

My approach has always been data first, logic to manipulate that data second, and UI/world representations are simply reflections of those objects and triggers for the functions, rather than being strictly necessary. Ideally, the systems for a game should be able to work equally well in a purely text-based RPG as they would in a game like Skyrim. An item should exist in an inventory in a purely data form- how that item is moved from one slot to another, or from one inventory to another, should be independent of the UI side. The UI’s job is to keep up-to-date on the object’s state, not to serve as a container for it- it can do its job well enough through delegates/events (the inventory is told to make a change, that change then triggers events to say “the data is now different, so everything interested should update themselves”, and the UI changes to reflect that new data).

This makes the most sense to me, because you can swap out your UI entirely and it never requires editing the inventory system at all.

That said, you should take care to separate out static data from instance data for each of your objects. Data that exists on ALL versions of a specific item type is static data- depending on your game, this could be the 2D icon, the 3D mesh, the name, the description, the gun’s type, the ammo types it uses, etc… Instance data is specific rolls to that weapon alone- the stuff that’s different from two drops of the same base weapon type. Static data should not be instanced from one weapon to the next, because there’s no need for it to be- just keep it in a database made specifically for that and toss references to its entry on each of the weapons made from it. Instance data is different from one object to the next, so that needs to be rolled uniquely to each one. This instance data, along with a reference to the static data, makes up most of the container we call an “inventory item”, and that should get stored in a collection for the player’s inventory.

The area should have its own inventory for weapons just tossed on the ground, and each container should have its own inventory as well- this makes it trivial to save these to disk when needed, as opposed to having them as physical objects in the scene’s hierarchy, or in the UI hierarchy. When a gun is shown in the game, on the ground as a pickup, it should just be a shell, the same as the icon in the UI- it only needs to reference the object in the area inventory, and have a collider/trigger so that you can actually pick it up, but the picking up should be handled by the player’s inventory controller and not a function of the weapon itself IMO- keep the physical representation of the object as simple as possible, and you’ll have no trouble at all pooling it for re-use later.

Anyways, that’s my take on how it should work, ideally, but every game is different, and every programmer does things in a slightly different way, so just consider it a single option, rather than the rule of thumb.

A list of game objects is indeed a list of references to objects. I understand this.

But as i understand it GameObjects are actual entities inside the unity scene. In a sense, If i have a reference to a game object. I have a reference to some kind of encapsulated class object which might contain in itself references to other things and which takes a certain amount of memory to store somewhere.

For example, I have a GameObject which contains a list of 200 floats. somewhere there is in memory this 200 floats stored. If the object also has a collider and what not, there is also memory allocated for it.

So, for a GameObject list, you have references, but also somewhere the Game Objects stored in memory.

If instead you have a list of “abstract” references, which are not real references in the sense of pointing to specific memory addresses, but merely some kind of reference system defined by the player,

For example a list of strings that simply says [“Shield”,“Gun”,“Etc”];

You could then have a piece of logic that iterates through the list and then CREATES (instances ?) a new game object based on whatever abstract meaning you attach to each string whenever it is necessary.

I am just not sure if having a list that references GameObjects which actually exist somewhere in the scene is not creating an unnecessary memory overhead.

Maybe i am not formulating my question correctly. possibly cause i’m new to unity and still not sure how unity handles the stuff.

Just as a simple example tho,

A player wants to collect an apple from a tree.

the tree can just be a static scenery object, the apples are individual objects, maybe even child objects of the tree, which the player can click on to harvest.

Let’s say each apple stores internally in as script, how much health it should give to the player when eaten.

When the player clicks on the apple, it should “disappear” from the world and go to the player inventory.

option 1)

When the player clicks the apple. the apple gameobject is destroyed and its contents serialized in some way, for example as a string that says “Apple,5”, for an apple that heals 5 hp, which is then stored in a string list inside the player’s game object.

If the player where to drop the apple on the ground a new game object would be instantiated with the desired parameters and the corresponding string removed from the string list inventory.

option 2)

When the player clicks the apple. The apple remains as a GameObject in game but is hidden in the 3d world, for example by turning off the mesh renderer and either moving it to coord (2000,2000,2000), or making it unclickable.

If the player where to drop the apple on the ground, the existing GameObject would just be moved to the player position and made to render visually again.

In the first case i had to destroy and create a new game object every time i interacted with it, but i saved myself from collecting large amounts of gameobjects just chilling in my scene.

In the second case i only created a gameobject once and then just manipulated it inside the scene, saving me from having to instantiate things over and over but likely having some memory overhead from all the objects just chilling somewhere in the scene.

I know the real answer is that it probably depends on the situation, but as i said this is a learning project, so my interest is more in learning about unity itself than how to make good inventories tbh. if you get what im saying.

Ya, truly depends on the situation (like, if you want the apple to ‘respawn’ in your scene)…

If you have an item you define as the apple, its definition might include the health you get by eating it, its inventory icon, and its world game object. If the apple doesn’t have any instance specific data, you’d need only 1 apple definition for any number of apples.

In any event, when you collect this apple from the game world, in some fashion, you can tell your inventory that you have an “apple” , do what you wish (hide/destroy the 3d object) and add it to your inventory.

I feel a bit like we’re repeating each other lol.

As for memory usage, it depends on how many world objects you have and if you have 1 definition for all apples or 1 definition + instance data. Even with strings that create objects in the game, they are created by a design you’ve made (to know what to do) - same memory there.

Also a bit comes down to with what you’re comfortable with, and what you think would be good, and easy enough to build/maintain. Not sure how helpful that is, but it’s a broad kinda topic… :slight_smile:

1 Like