Search Unity

[Inject] Explain how Injection work in ECS

Discussion in 'Entity Component System' started by NoDumbQuestion, Jul 20, 2018.

  1. NoDumbQuestion

    NoDumbQuestion

    Joined:
    Nov 10, 2017
    Posts:
    186
    From Doc:
    I'm kinda lost at what dependencies we are talking about here. So I will break down from my point of view.

    Code (CSharp):
    1.     public struct Group
    2.     {
    3.         [ReadOnly]
    4.         public ComponentDataArray<Position> Position;
    5.  
    6.         public EntityArray Entities;
    7.  
    8.         public GameObjectArray GameObjects;
    9.      
    10.         public int Length;
    11.     }
    12.     [Inject] private Group m_Group;
    And from my limit understanding, [Inject] magically help find all entity that match same Struct(have Position,GameObjects and must be entity) as I/me provided. So I can loop through all of that group OnUpdate.

    And when I use "EntityManager.Instantiate", I have to call "UpdateInjectedComponentGroups()" to tell my script to update Group declare inside this script or it will call update on all Injected Groups. Otherwise, my Group would just be empty.

    So I guess my [Inject] group won't update by itself. Does it only update during bootstrap/Start or somewhere else?

    Am I missing something important here?
     
  2. petermernyei

    petermernyei

    Joined:
    Jul 20, 2018
    Posts:
    1
    UpdateInjectedComponentGroups() is automatically called every tick before the OnUpdate() method. I don't think you should ever have a good reason to call it yourself - the intended use is to do all your logic in OnUpdate(), at which point you know everything has been injected. If you create a new entity, it will be automatically found and injected into any system that starts updating later in the same tick, or in later ticks (not the one currently running).
     
  3. M_R

    M_R

    Joined:
    Apr 15, 2015
    Posts:
    559
    each system updates the injection groups before calling OnUpdate().

    you should not call
    UpdateInjectedComponentGroups
    .
    if you call
    EntityManager.Instantiate
    , injections are invalidated because order of entities may change.
    if you need to create/destroy entities or add/remove components inside the update loop, either use
    PostUpdateCommands
    or batch them manually and Instantiate after the loop.

    i.e. instead of
    Code (csharp):
    1.  void OnUpdate() {
    2.     for (int i = 0; i < group.Length; i++) if (condition) EntityManager.Instantiate(prefab); // this breaks the group
    3. }
    you can do
    Code (csharp):
    1. void OnUpdate() {
    2.     int count = 0;
    3.     for (int i = 0; i < group.Length; i++) if (condition) count++;
    4.     if (count > 0) {
    5.         var dest = new NativeArray<Entity>(count, Allocator.Temp);
    6.         EntityManager.Instantiate(prefab, dest); // batches many instantiations
    7.         // dest contains the instantiated entities
    8.         dest.Dispose();
    9.     }
    10. }
     
    NoDumbQuestion likes this.