Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

[SOLVED] Get nativearray with new entities from target world when using MoveEntitiesFrom()

Discussion in 'Entity Component System' started by meanmonkey, Dec 9, 2018.

  1. meanmonkey

    meanmonkey

    Joined:
    Nov 13, 2014
    Posts:
    148
    I want to use ExclusiveEntityTransaction to mass create/prepare entities in the background in a separate world and move them later to the render world with MoveEntitiesFrom (which works fine)

    But I need a nativearray with entities for later batch destruction.

    I am batch creating the entites in the "loading" world so I have a nativearray with entities, but as they are moved to another world, its useless, as these entites are from the source world and do not exist anymore after moving (Which seems natural to me as the target world will use completely different indices).

    So I wonder if there is any clean way to get back a nativearray of entites from the target world ?
     
  2. 5argon

    5argon

    Joined:
    Jun 10, 2013
    Posts:
    1,555
    I think your solution is EntityRemapUtility. MoveEntitiesFrom has an overload which populates a native array of EntityRemapInfo. Use EntityManager.CreateEntityRemapArray of what world you are moving entities from. Then after the move, this map would tell you what they were can become what they are now. If you then use your useless native array of entities with this remapper (Use by iterating and call EntityRemapUtility.RemapEntity on each), I think you can turn the content of that array into valid entities.

    (Also for batch destruction I would just attach some kind of tag component on them before moving to the main world, and then use component group query to destroy)
     
  3. meanmonkey

    meanmonkey

    Joined:
    Nov 13, 2014
    Posts:
    148
    Yes! Thanks, that did it!

    Code (CSharp):
    1.  
    2. ExclusiveEntityTransaction entityTransaction = loadingEntityManager.BeginExclusiveEntityTransaction();
    3. NativeArray<Entity> entities = new NativeArray<Entity>(entityCount, Allocator.Persistent);
    4. entityTransaction.CreateEntity(entityArcheType, entities);
    5.  
    6. // ...
    7. // Do component stuff
    8. // ...
    9.  
    10. loadingEntityManager.EndExclusiveEntityTransaction();
    11. NativeArray<EntityRemapUtility.EntityRemapInfo> entityRemapping = loadingEntityManager.CreateEntityRemapArray(Allocator.Temp);
    12. renderEntityManager.MoveEntitiesFrom(loadingEntityManager, entityRemapping);
    13.  
    14. for (int i = 0; i < entities.Length; i++)
    15. {
    16.      entities[i] = EntityRemapUtility.RemapEntity(ref entityRemapping, entities[i]);
    17. }                  
    18.  
    19. entityRemapping.Dispose();
    20.  
    21.  
     
    Last edited: Dec 10, 2018
    Egad_McDad, Zyblade, PaulUsul and 2 others like this.
  4. merobbins5

    merobbins5

    Joined:
    Jun 16, 2020
    Posts:
    7
    Does this method still work? I'm getting a BlobAssetReference is not valid error when trying this now.

     
  5. merobbins5

    merobbins5

    Joined:
    Jun 16, 2020
    Posts:
    7
    Code (CSharp):
    1.             World localWorld = new World("local world");
    2.  
    3.             var transaction = localWorld.EntityManager.BeginExclusiveEntityTransaction();
    4.  
    5.             var entities = new NativeArray<Entity>(3, Allocator.Persistent);
    6.            
    7.             using (var reader = new StreamBinaryReader(_savedWorldFilename))
    8.             {
    9.                 SerializeUtility.DeserializeWorld(transaction, reader, unityMappingTable);
    10.             }
    11.  
    12.             localWorld.EntityManager.EndExclusiveEntityTransaction();
    13.  
    14.             NativeArray<EntityRemapUtility.EntityRemapInfo> entityRemapping = localWorld.EntityManager.CreateEntityRemapArray(Allocator.TempJob);
    15.  
    16.             World.DefaultGameObjectInjectionWorld.EntityManager.CopyAndReplaceEntitiesFrom(localWorld.EntityManager);
    17.  
    18.             localWorld.Dispose();
    19.  
    20.             for(int i = 0; i < entities.Length; i++)
    21.             {
    22.                   entities[i] = EntityRemapUtility.RemapEntity(ref entityRemapping, entities[i]);
    23.             }
    24.             entityRemapping.Dispose();