Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Editor friendly system for item management and creation advice

Discussion in 'Scripting' started by invisage, Jun 19, 2022.

  1. invisage

    invisage

    Joined:
    Jun 27, 2019
    Posts:
    23
    My objective is to have a system that is editor friendly for designers/artists on a team. I have come up with an initial system that works but would like to see if there is a better way, especially as more content is added.

    The basic idea is that there are base Items. These base Items can be combined to make other items (let's call them Ingredients and Products). To make these user-friendly I am using serialized enums for the Ingredients and scriptable objects for each Product to select a list of these Ingredients(enums).

    The problem comes in at the next step where I want a class to be able to check for particular Items. The class needs to check for both Ingredients and Products, as either may be required. For the moment the idea is that only ONE Item will be required (but later might expand the idea/scope to require more than one).

    So as part of the Product class, I have also created an enum of the different products. So what I have done so far is:

    Item:

    Code (CSharp):
    1. public class Item
    2. {
    3.     public TypeOfItem ItemType { get; }
    4.  
    5.     public Item(TypeOfItem itemType)
    6.     {
    7.         ItemType = itemType;
    8.     }
    9. }
    10.  
    11. public enum TypeOfItem
    12. {
    13.     Bread,
    14.     Ham,
    15.     Cheese,
    16.     HamSandwich,
    17.     CheeseSandwich
    18. }
    Ingredient:

    Code (CSharp):
    1. public class Ingredient : Item
    2. {
    3.     public Ingredient(TypeOfIngredient ingredient) : base((TypeOfItem)ingredient)
    4.     {
    5.     }
    6. }
    7.  
    8. public enum TypeOfIngredient
    9. {
    10.     Bread = TypeOfItem.Bread,
    11.     Ham = TypeOfItem.Ham,
    12.     Cheese = TypeOfItem.Cheese
    13. }
    Product:

    Code (CSharp):
    1. public class Product : Item
    2. {
    3.     public Product(TypeOfProduct product)  : base((TypeOfItem)product)
    4.     {
    5.     }
    6. }
    7.  
    8. public enum TypeOfProduct
    9. {
    10.     HamSandwich = TypeOfItem.HamSandwich,
    11.     CheeseSandwich = TypeOfItem.CheeseSandwich
    12. }
    And when creating a new Ingredient or Product it automatically is caste to TypeOfItem enum so its easy to do checks etc

    Again all the above works BUT I am double handling the creation of each Item and I can also see where errors could pop up. If I wasn't wanting to expose these to the editor I could think of other ways of handling it.

    Any thoughts on a better system would be much appreciated :)
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,710
    Kinda smells like maybe you want to be using ScriptableObjects... look up a few online tutorials because they allow super-simple basic editor integration and are perfect for predefined data like objects.

    ALSO, at the larger scale of an inventory, keep this in mind:

    These things (character customization, inventories, shop systems) are fairly tricky hairy beasts, definitely deep in advanced coding territory. They 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

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

    - can you have multiple items? Is there a limit?
    - 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.

    Or... do like I like to do: just jump in and make it up as you go. It is SOFT-ware after all... evolve it as you go! :)

    Breaking down a large problem such as inventory:

    https://forum.unity.com/threads/weapon-inventory-and-how-to-script-weapons.1046236/#post-6769558

    "Combining a bunch of stuff into one line always feels satisfying, but it's always a PITA to debug." - Star Manta on the Unity3D forums
     
    invisage and spiney199 like this.
  3. invisage

    invisage

    Joined:
    Jun 27, 2019
    Posts:
    23
    Thanks Kurt.

    I was already using ScriptableObjects for the system to check what Ingredients were needed to make a Product. Didn't occur to me to use SciptableOjbects to create the actual Items themselves. Quickly changing to that provided the Editor functionality I wanted. In fact, its made it even more user friendly. Was able to do away with most of the enums, just using them now for Item types.
     
    Kurt-Dekker likes this.
  4. Bunny83

    Bunny83

    Joined:
    Oct 18, 2010
    Posts:
    3,524
    As Kurt said, just using a single ScriptableObject type for everything is the easiest solution. So you just have an "Item" scriptable object. An item may have a recipe but does not have to. A recipe could be represented by a List of ItemStacks where ItemStack would simply be a class that references another Item and specifies the amount required. So you can design arbitrary complex recipies for an unlimited about of different Items.