Search Unity

Entity Prototypes

Discussion in 'Entity Component System' started by SubPixelPerfect, Mar 26, 2018.

  1. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    ECS has a great way to clone existing entities using EntityManager.Instantiate(entity)

    Seems logical for me to construct and configure a "prototype" entity for each unit kind at game start, and then clone those prototypes as many times as needed during the game.

    But, to do so, i need to make all systems to ignore this prototype entity.

    I wonder if there exist any way to disable entity, or hide it form all systems?
     
  2. Krajca

    Krajca

    Joined:
    May 6, 2014
    Posts:
    347
    "archetype" is what you are looking for.
     
  3. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    nope
    archetype contain only entity type definition (list of component types) but do not contain state (component values)

    what i like to achieve is to get a fully configured entity, kind of "prefab" but in memory and ready to Instantiate,
    with linked shared-mesh/shared-material and with defined bounds/hp/armor/etc
     
  4. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    solution i see is to add a "Prototype" tag component to entity prototype,
    and to make all systems to skip any entities that have it

    but again not sure if it possible to make system iterate over some set of components excluding one,
    would be nice to have something like:
    [inject (exclude="Prototype")]
     
    illinar likes this.
  5. gamevanilla

    gamevanilla

    Joined:
    Dec 28, 2015
    Posts:
    968
    You can use SubtractiveComponent for that (there is an example here).
     
    SubPixelPerfect likes this.
  6. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    thank you gamevanilla
    awesome, missed it

    but there is another thing that blocking me from starting to implement it,
    i'd like to use some builtin systems like MeshInstanceRendererSystem
    i wonder how to override ComponentGroup for those systems

    and also how to make default world not to auto load built in system and load extended istead
     
  7. Arakon

    Arakon

    Joined:
    Mar 8, 2014
    Posts:
    23
    You could keep your prototypes in a separate World.
    The system supports one world by default, but you can manually construct other ones. I'm not sure of the syntax - just saw references in the docs.
     
  8. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    Yes, here is a tread on this forum, and i was able to add second world, but another world will have another entity manager
     
  9. DwinTeimlon

    DwinTeimlon

    Joined:
    Feb 25, 2016
    Posts:
    300
    Not sure if I am getting what you actually want, but to make use of the current MeshInstanceRendererSystem you just add a MeshInstanRenderer and a TransformMatrix to your entity and it will use it automatically.

    Also you can disable systems via
    Code (CSharp):
    1. World.Active.GetOrCreateManager<AnySystemName>.Enabled = false
    to enable/disable systems.
     
  10. SubPixelPerfect

    SubPixelPerfect

    Joined:
    Oct 14, 2015
    Posts:
    224
    yes I understand how to add/remove/disable systems
    what i don't understand is:
    1) how to extend existing system and override its ComponentGroup
    2) how to make default world to use extended system instead of original (delete or disable old one that was added automatically will work, but this is not kosher way)
    3) default world is created automatically, and all system that exist in the project are automatically added to it, but if i decide to create and configure my own world by hands, how to disable default world auto-generation
     
    Last edited: Mar 26, 2018
  11. floboc

    floboc

    Joined:
    Oct 31, 2017
    Posts:
    91
    Did you find a solution to this problem appart from using a "Prototype" tag ?
    I am not sure how to copy entities from one world to another...
     
  12. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    @SubPixelPerfect I'm trying to fully understand what you're intention for this is. I know you'll essentially be writing more code to handle spawning, but these cases should be constrained to very few systems. Might even make sense to constrain it to only one system for each different prototype to limit it's usages.

    Another way to approach this would maybe be something in line with a type that contains the Archetype alongside a collection of each of the component values that should be set.

    Code (CSharp):
    1. public  struct Prototype
    2. {
    3.     public EntityArchetype Archetype;
    4.     public NativeList<IComponentData> componentValues;
    5. }
    Then to instantiate I'd create the following extension method:

    Code (CSharp):
    1. public static class EntityManagerExtensions
    2. {
    3.     public static Entity Instantiate(this EntityManager entityManager, Prototype prototype)
    4.     {
    5.         Entity entity = entityManager.CreateEntity(prototype.Archetype);
    6.         for (int i = 0; i < prototype.componentValues.Lenght;  i++)
    7.         {
    8.             entityManager.SetComponentData(entity, prototype.componentValues[i[);
    9.         }
    10.         return entity;
    11.     }
    12. }
    This way you won't be creating a bunch of entities that have to be ignored by systems, but rather creating a prototype for specific usage that can be created in a generic way. There's even room for extending this regarding shared components.
     
    Last edited: May 17, 2018
    DotusX and Deleted User like this.
  13. floboc

    floboc

    Joined:
    Oct 31, 2017
    Posts:
    91
    Well it would be nice to be able at least to create such prototypes through an editor inspector instead of manually setting all the values in the code, and then instantiate it through some EntityPrototype class, just as for Prefabs.

    It would also enable faster iteration since this might enable to change default value during play instead of having to recompile your system just to change a value.
    It could also enable some data compression during serialization by allowing to just pass some prototype ID instead of the full entity components if they were not changed.

    At the moment in my code, I have a system specialized in instantiating entities. However, it has a huge switch on something like EntityType, and dozens of line of codes to add all required components with correct values for each. If you have dozens of different entities it can be a nightmare in my opinion
     
  14. MadeFromPolygons

    MadeFromPolygons

    Joined:
    Oct 5, 2013
    Posts:
    3,983
    They have already said this is what the final version is intended to be able to do.
     
  15. floboc

    floboc

    Joined:
    Oct 31, 2017
    Posts:
    91
    Yes, I was answering to the comment of Cyberwiz, who was asking why we would need prototypes.
     
    MadeFromPolygons likes this.
  16. LazyGameDevZA

    LazyGameDevZA

    Joined:
    Nov 10, 2016
    Posts:
    143
    Regarding creating it through the editor I think creating a prefab where you attach the components would work as well. Just add some hookup code to go and create the `EntityArchetype` on startup or something like that and you'll be able to pull the components everytime it gets created or something like that. While these things are nice. I do believe Unity will be delivering on their promise of being able to view these in the editor.
     
  17. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    Currently subtractive component is the best way to do it.

    In any case we are definitely aware that we need to solve the issue of how do I store a prototype / prefab in my world.
     
    SubPixelPerfect likes this.