Search Unity

Question Need help with NativeArray deallocating

Discussion in 'Entity Component System' started by oliverfrank321, Feb 12, 2023.

  1. oliverfrank321

    oliverfrank321

    Joined:
    Nov 16, 2017
    Posts:
    1
    Heya, having some issues with ECS 1.0. I'm currently trying to populate a big array, then attach that array to a new entity I'm instantiating as part of a component. Because the population is a fairly heavy computation (it's terrain generation), I want to run this all in a job on a seperate thread. Currently, the code looks like this:

    Code (CSharp):
    1. NativeArray3D<BlockType> chunk = new NativeArray3D<BlockType>(
    2.     ChunkGenerator.ChunkSize
    3. );
    4. JobHandle chunkGenJob = ChunkGenerator.GenerateChunk(chunk, 0, chunkPos, 0f);
    5. new CreateChunkJob
    6. {
    7.     prefab = chunkManager.ChunkPrefab,
    8.     ecb = SystemAPI
    9.         .GetSingleton<BeginSimulationEntityCommandBufferSystem.Singleton>()
    10.         .CreateCommandBuffer(World.Unmanaged),
    11.     chunkPos = chunkPos,
    12.     chunk = chunk,
    13. }.Schedule(chunkGenJob).Complete();
    GenerateChunk is scheduling a job to populate `chunk`, which I've allocated as persistent (in the contructor of NativeArray3D). Then, I schedule the job to instantiate the object, and set it's components:

    Code (CSharp):
    1. public partial struct CreateChunkJob : IJob
    2. {
    3.     public Entity prefab;
    4.     public EntityCommandBuffer ecb;
    5.     public int2 chunkPos;
    6.     public NativeArray3D<BlockType> chunk;
    7.     public void Execute()
    8.     {
    9.         Entity newChunk = ecb.Instantiate(prefab);
    10.         ecb.SetComponent(
    11.             newChunk,
    12.             LocalTransform.FromPosition(new Vector3(chunkPos.x, 0, chunkPos.y))
    13.         );
    14.         ecb.SetComponent(
    15.             newChunk,
    16.             new ChunkDataComponent
    17.             {
    18.                 Blocks = chunk,
    19.                 NeedsRemesh = true,
    20.                 WorldPosition = chunkPos,
    21.             }
    22.        );
    23.     }
    24. }
    My issue is that the system that ends up using this data to create a mesh throws an error saying that the underlying array of the chunk is deallocated. This is not an issue if I run my instantiation/ECB code outside of a job. Thanks for any help.
     
  2. Antypodish

    Antypodish

    Joined:
    Apr 29, 2014
    Posts:
    10,770
    Any reason you put an array on the chunk
    Seems like pointless excersise, if you just generating the terrain.

    Just allocate native array, when system starts, make it let's say persistent. Then pass Native array into the job, populate and do whatever need to. Then eventually dispose, if you don't need persistent array.
     
  3. suity447

    suity447

    Joined:
    Oct 18, 2022
    Posts:
    33
    I have recently run into the same problem. I think that when adding/setting a component with a native container via an EntityCommandBuffer the native container on the component ends up with the same allocator flags as the temporary container in the ECB. I am not sure if this is a bug or intended behavior. However I think the documentation should mention it. As you have already mentioned this does not occur when the component is set on the main thread. Another workaround (if applicable) is using an dynamic buffer which can be used as a native array. For dynamic buffers this problem does not occur.