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

Best way to spawn many prefabs and have them reference each other in components

Discussion in 'Entity Component System' started by Abbrew, Apr 4, 2022.

  1. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    I have Unit which spawns these prefab Entities: a single Officer, a single Formation, and many Soldiers. Officers, Formations, and Soldiers need to reference each other in their components. However, this can quickly become extremely complicated since instantiated Entities have negative indices right after creation, and should not be stored in components until the ECB has played back and converted the negative indices to positive ones. Are there any good patterns for creating and linking these spawned entities?
     
  2. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    Using ECB Add/Set component works correctly with the negative entity indices. ECB remaps them during playback.
     
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,653
    Small additional note:
    Only if add/set processed in the same ECB where temp entity index was created.
     
    DreamingImLatios likes this.
  4. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    Correct, though you might only be referring to this case

    Code (CSharp):
    1. var created = ecb.Instantiate(prefab);
    2.  
    3. ecb.SetComponent(created, new SomeComponent());
    I am wondering about this case

    Code (CSharp):
    1. var created = ecb.Instantiate(prefab);
    2.  
    3. ecb.SetComponent(existing, new OtherComponent { entity = created });
    Is the ECB smart enough to remap the entity correctly in the second case?
     
  5. TRS6123

    TRS6123

    Joined:
    May 16, 2015
    Posts:
    246
    Yes
     
  6. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    Thanks. Last question is regarding the whole "same ECB" requirement. If I do

    Code (CSharp):
    1. var created = ecb.Instantiate(prefab);
    2. ecb.SetComponent(existing, new OtherComponent { entity = created });
    and the negative Entity stays in OtherComponent for several frames, which means the original ECB has disappeared, then what happens when a new ECB several frames later tries to do something like

    Code (CSharp):
    1. var otherComponent = GetComponent<OtherComponent>(existing);
    2.  
    3. var previouslyCreated = otherComponent.entity;
    4.  
    5. ecb.SetComponent(previouslyCreated, new AnotherComponent());
    where previouslyCreated is still a negative Entity. Basically, do I never have to worry about negative Entities?
     
  7. Abbrew

    Abbrew

    Joined:
    Jan 1, 2018
    Posts:
    417
    Also, could I use GetComponent on newly instantiated entities?
     
  8. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,983
    That should be impossible. SetComponent has to be played back from the ECB. And when it does, it will remap the entity. When you call GetComponent, you either get the value of the component before ECB.SetComponent, or after ECB.Playback in which case the value is already remapped. The only way I could see this failing is if you create and destroy the same entity in the same ECB. I'm not sure if that is possible to do, but if it is, it is stupid, so don't do it.
     
    Abbrew likes this.
  9. TRS6123

    TRS6123

    Joined:
    May 16, 2015
    Posts:
    246
    Not before the ECB that instantiated the entity is played back
     
    Abbrew likes this.