Search Unity

Collections of Entities

Discussion in 'Entity Component System' started by JooleanLogic, May 14, 2018.

  1. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    How do you go about representing collections of entities like an inventory given that you can't store dynamic arrays on components? And then how would you go about processing the inventory of just one character?

    I've thought of two options.
    1. is to invert the hierarchy where you add a parent component to every item in the inventory so it knows which inventory it belongs to. But how then do you process just a single character's inventory out of the many characters in a game?

    E.g. Imagine an inventory that contains health potions and for a given character, you want to consume all health potions until its health is full?

    In a top down approach, you'd go
    Code (CSharp):
    1. for each Entity in character.inventory
    2.     process entity...
    In a bottom up approach, you'd have to filter every inventory item in the game on a given character.
    Code (CSharp):
    1. for each InventoryItem in game
    2.     if inventoryItem.parent == characterToProcessEntity
    3.         process entity...
    2. The other alternative is to store arrays of entities offworld in a global hashmap and then just store the hashkey on a component.

    Or should you maybe use FixedArray<Entity> and size it to the maximum size required?
     
  2. kru

    kru

    Joined:
    Jan 19, 2013
    Posts:
    452
  3. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    Yes you could. That's just like my second code snippet above but it doesn't seem a very efficient solution to iterate the entire set every time you just want a subset.
    The filter scenario makes some logical sense as you're essentially asking for a subset of entities that all share the same archetype (I.e. give me all inventory items belonging to character x) and it may even be faster than an array (with unordered entities) on small data sets due to cache coherency. However a simple array could already contain all the entities you need and seems structurally simpler when it comes to game logic.

    Searching online, other ecs systems allow components to store reference data so you can store more complex data structures on components. Unity's ecs is very strict which is obviously good for performance in some types of games, however it requires more complex solutions to game logic processing which are otherwise very easy in OO. Or maybe not. I'm not fluent in the ecs paradigm so perhaps there's easy solutions to these things.

    I'm just trying to convert my simple Monobehaviour based game to ecs atm and it sure is challenging the ol' grey matter. :)
     
  4. mike_acton

    mike_acton

    Unity Technologies

    Joined:
    Nov 21, 2017
    Posts:
    110
    It all depends on what is processing the data most commonly. But let's say inventory processing is not as common, so indirection here makes sense, then separate entities representing items in your inventory and have those reference the entities that hold the inventory and the actual item in the inventory, respectively. Like:

    InventoryHolderComponent { Entity }
    InventoryItemComponent { Entity }

    If inventoryholder is relatively stable (which it probably is), you can make that a shared component - but I'd only really recommend that if your inventories are quite large, otherwise you'll be creating a lot of small chunks wasting most of the space in them.
     
  5. JooleanLogic

    JooleanLogic

    Joined:
    Mar 1, 2018
    Posts:
    447
    Yeah this is what I'm going with at the moment and then just filtering by the InventoryHolderComponent. It's not ideal but there's only a small set to filter on so I don't imagine it'll matter.