I started working on a factory game (satisfactory, factorio type of games). I Got a building system down and some basic inventory that processes recipes. Now i want to implement a inventory system.
Started off with a Inventory base, then using that made BuildingInventory and PlayerInventory. The thing is that buildin Inventory has to have input output slots. and the Player just normal slots with hotbar. I got a supper basic version to work with dynamic UI Slots but hit a wall when needing to transfer between the two inventories then AI got involved and messed it all up. So i reverted the changes and back to the simple system
Items are setup using SO and recipes are setup using a list of a struct or class with ItemSO and amount
Do i setup one InventoryManager, then use a Interface or something similar?
Are there any tutorials, guides or even books on Inventory systems that persist if the gameobject is not loaded / rendered.
You âwantâ to, or you want to have one? There are plenty solutions already available. Of course DIY has its merits, but donât just blindly roll your own because itâs never as simple as one would expect.
You just paraphrased some fragments of your current setup. Thereâs just not enough detail to provide concrete suggestions.
Just one general rule of thumb: data, data, data.
Decouple your data from the architecture and anything you build around it will be a lot easier. You probably donât even need a âbaseâ class, nor would you need separate classes for Building, Player, etc inventories. Think database, not OOP.
Like I said, data. You can persist data any way you like. Whatever code uses it and what that codeâs lifetime is wonât matter anymore.
This can help you decide what kind of a system and level of complexity you need. As CodeSmile already posted above, these things are ânever as simple as one would expect.â
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:
Do you know any guides and material that cover this topic. I want to do it DIY instead of the shelf solution.
Current system that i have just to test if everything works, Its just list that i add remove items.
And dont have any experience in this type of games. Mainly FPS games and a bit of Multiplayer with that.
I was thinking that i would have a âbaseâ that has basic function for moving items then for specific building types add extra functions and Lists for inventorys
Not necessarily, you can write a good system for managing inventory items purely with static classes/methods operating on data.
For a Satisfactory game you have:
Resources - generate items over time, this may even include animals as they may be a form of resource too. Also specifies whether the source is replenishable, infinite or finite.
Items (a single mesh may represent 1-n items)
Item attributes - some items are multi-use, for instance you can have multiple items be a âconsumable energy sourceâ with a varying amount of energy provided (leaves, wood, coal, âŚ). For that you can define an attribute âenergy sourceâ and provide the amount of energy per use.
Ports - this is where you plug in the item of the desired type, these specify allowed types such as âanyâ or âcopper wireâ or âenergy sourceâ
Best start by defining what data you need (item, recipe, resources, etc). Then build the systems around modifying that data. Start with the simplemost resource transfer - this doesnât even need a visualization, you can (and should) make that work purely from a data perspective. Think of acquiring coal over time, the player manually adds that into a burner, this generates electricity (another resource), this powers a miner (and needs a powerline connection), miner extracts iron ore over time, and this ore gets fed into some machine through a conveyor, which then turns the iron ore into iron ingots and places them at the output port, which is a single inventory slot and gets filled when there is no conveyor attached or the conveyor is âfullâ.
Youâll have enough on your hands to make this part work and how to connect the dots. But it would be a good exercise to think of all the resource aspects, especially the less obvious ones like animal spawners and electricity (imagine this as having infinite speed on the power line âconveyorâ - it just needs a connection). That way youâll be able to meld many things together rather than having special case code for things that in reality are generalizable.
For a factory game youâd want to pretty much be able to represent as much as your game state entirely as data. There should be a clear distinction, and really, it will mean most of your game world just acts as entry points into the data layer. You can have a top-most data object that contains most, if not all of the data of your game world.
An assembly machine game object/prefab in the game world, for example, would just have some means to hook into its respective backing data, so it can show the user UI on whatâs going on, and naturally allow the user to manipulate whatâs going on through it.
The same concept can apply with an inventory system. In my current project, any âcontainerâ in the game world doesnât directly handles its content. It simply has an ID that can look up its contents within a greater, purely data registry of container contents. It makes it a lot easier to implement systems that require the contents of one or more container, as you donât have any game-object-ey things in the way.
And if youâre smart, you can make all this data innately serializable, and thus your save games are much easier to implement.
By default I donât do that anymore but rather pack all these fields in a [Serializable] struct and that struct is the only field in the SO.
The benefit of doing so is that you can pass around your data as is, without the SO âattachedâ. This has many benefits, such as being able to modify any of the fields at runtime without applying this modification to everything using the SO.
For instance, you may find you need to alter the DisplayName or Icon at some point, or raise the MaxStackSize but only for a particular machine, or just for the remote playerâs inventory but not the local playerâs inventory. Reasons are aplenty. In that case, you can just modify the struct fields without affecting other machines/players.
Note that I personally prefer struct because I tend to want to leave the path towards Jobs open and am familiar with the pass-by-value caveats. But it can also be a class and passed by reference.