Search Unity

Adding component using PostUpdateCommands deallocates array? (hybrid)

Discussion in 'Entity Component System' started by Aeris130, Jul 1, 2018.

  1. Aeris130

    Aeris130

    Joined:
    Mar 30, 2017
    Posts:
    1
    At the time of running, there's an entity (E1) in the system with the component MyComponent (struct). There's also a system that iterates over all entities with MyComponent.

    When (in that system) a new entity (E2) is created from a gameobject, scheduling a copy of MyComponent to be added to E2 using PostUpdateCommands seems to deallocate the ComponentDataArray holding E1's component.

    Code (CSharp):
    1. public class MyEntitySystem : ComponentSystem {  
    2.  
    3.     public struct Data {
    4.  
    5.         public ComponentDataArray<MyComponent> MyComponents;
    6.         public int Length;
    7.  
    8.     }
    9.  
    10.     [Inject] Data myData;
    11.  
    12.     protected override void OnUpdate() {
    13.  
    14.         // Step 1: Create a new entity/gameobject
    15.         var prefab = (GameObject)Resources.Load("MyPrefab", typeof(GameObject));
    16.         GameObject go = Object.Instantiate(prefab);
    17.         Entity e2 = go.GetComponent<GameObjectEntity>().Entity;
    18.  
    19.         // Step 2: Add MyComponent at some later time
    20.         PostUpdateCommands.AddComponent(e2, new MyComponent());
    21.  
    22.         // Step 3: Try to iterate over existing objects with MyComponent for now
    23.         for (int i = 0; i < myData.Length; i++) {          
    24.             MyComponent myComp = myData.MyComponents[i]; // <- Deallocated
    25.         }
    26.  
    27.     }
    28.  
    29. }
    Is this a wrong usage of PostUpdateCommands, or just a limitation in the hybrid approach? Calling CreateEntity using PostUpdateCommands isn't possible with prefabs.
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    One way is to move prefab instantiation somewhere else like OnStartRunning so in OnUpdate it reinject again or you can call `UpdateInjectedComponentGroups()` after prefab instantiation to counter the create entity data invalidation inside GameObjectEntity's OnEnable.
     
    eizenhorn likes this.
  3. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Problem not in entity command buffer, problem in GO Instantiate, because GameObgectEntity added new entity in OnEnable than reallocated memory for chunks.
     
  4. eizenhorn

    eizenhorn

    Joined:
    Oct 17, 2016
    Posts:
    2,683
    Ah, ahead of :)