Search Unity

Issues with automatic deallocation of a NativeList inside of ISharedComponentData

Discussion in 'Entity Component System' started by Matt_De_Boss_Developer, Nov 29, 2019.

  1. Matt_De_Boss_Developer

    Matt_De_Boss_Developer

    Joined:
    Oct 17, 2014
    Posts:
    46
    So basically, Unity is showing the error "The NativeArray has been deallocated, it is not allowed to access it" even though I am not deallocating in any of my code. I have 3 NativeLists inside of ISharedComponentData that I am attempting to let 2 different systems use. I generate mesh data in one job system, then I attempt to transfer that data to a component system using this SharedComponentData. Code is below:

    Code (CSharp):
    1. using Unity.Entities;
    2. using Unity.Jobs;
    3. using Unity.Collections;
    4. using Unity.Burst;
    5. using UnityEngine;
    6. using Unity.Rendering;
    7.  
    8.  
    9. using static Unity.Mathematics.math;
    10.  
    11. using Unity.Mathematics;
    12. public class ChunkMeshingSystem : JobComponentSystem
    13. {
    14.     EntityQuery chunksQuery; //and entity query that will grab all the chunks currently in the world
    15.     NativeArray<Entity> chunks;
    16.     Entity chunk;
    17.  
    18.     NativeHashMap<uint, Edge> activeEdges;
    19.     NativeHashMap<uint, uint> activeVoxels;
    20.     NativeHashMap<uint, uint> vertexIndices;
    21.  
    22.  
    23.     NativeArray<int4> AXIS_OFFSET;
    24.     NativeArray<int4> EDGE_NODE_OFFSETS;
    25.     NativeArray<uint> ENCODED_EDGE_OFFSETS;
    26.     NativeArray<uint> ENCODED_EDGE_NODE_OFFSETS;
    27.  
    28.  
    29.     NativeList<float3> vertices;
    30.     NativeList<float3> normals;
    31.     NativeList<int> triangles;
    32.  
    33.  
    34.     static int4[] AXIS_OFFSET_ARRAY =
    35.     {
    36.         int4(1, 0, 0, 0),
    37.         int4(0, 1, 0, 0),
    38.         int4(0, 0, 1, 0)
    39.     };
    40.  
    41.     static int4[] EDGE_NODE_OFFSETS_ARRAY =
    42.     {
    43.         int4(0), int4(0, 0, 1, 0), int4(0, 1, 0, 0), int4(0, 1, 1, 0),
    44.         int4(0), int4(1, 0, 0, 0), int4(0, 0, 1, 0), int4(1, 0, 1, 0),
    45.         int4(0), int4(0, 1, 0, 0), int4(1, 0, 0, 0), int4(1, 1, 0, 0),
    46.     };
    47.  
    48.     static uint[] ENCODED_EDGE_OFFSETS_ARRAY =
    49.         {
    50.         0x00000000,
    51.         0x00100000,
    52.         0x00000400,
    53.         0x00100400,
    54.         0x40000000,
    55.         0x40100000,
    56.         0x40000001,
    57.         0x40100001,
    58.         0x80000000,
    59.         0x80000400,
    60.         0x80000001,
    61.         0x80000401
    62.         };
    63.  
    64.  
    65.     static uint[] ENCODED_EDGE_NODE_OFFSETS_ARRAY =
    66.     {
    67.         0x00000000,
    68.         0x00100000,
    69.         0x00000400,
    70.         0x00100400,
    71.         0x00000000,
    72.         0x00000001,
    73.         0x00100000,
    74.         0x00100001,
    75.         0x00000000,
    76.         0x00000400,
    77.         0x00000001,
    78.         0x00000401,
    79.     };
    80.  
    81.  
    82.     private EntityCommandBufferSystem entityCommandBufferSystem;
    83.  
    84.     protected override void OnCreate()
    85.     {
    86.         chunksQuery = EntityManager.CreateEntityQuery(typeof(NeedsMeshing)); //initialize the chunk query to grab everything with "ChunkInfo" on it
    87.  
    88.         activeEdges = new NativeHashMap<uint, Edge>(64 * 64 * 64 * 3, Allocator.Persistent);
    89.         activeVoxels = new NativeHashMap<uint, uint>(64 * 64 * 64, Allocator.Persistent);
    90.         vertexIndices = new NativeHashMap<uint, uint>(64 * 64 * 64, Allocator.Persistent);
    91.  
    92.         vertices = new NativeList<float3>(64 * 64 * 64, Allocator.Persistent);
    93.         normals = new NativeList<float3>(64 * 64 * 64, Allocator.Persistent);
    94.         triangles = new NativeList<int>(64 * 64 * 64, Allocator.Persistent);
    95.  
    96.         AXIS_OFFSET = new NativeArray<int4>(3, Allocator.Persistent);
    97.         AXIS_OFFSET.CopyFrom(AXIS_OFFSET_ARRAY);
    98.  
    99.         EDGE_NODE_OFFSETS = new NativeArray<int4>(12, Allocator.Persistent);
    100.         EDGE_NODE_OFFSETS.CopyFrom(EDGE_NODE_OFFSETS_ARRAY);
    101.  
    102.         ENCODED_EDGE_OFFSETS = new NativeArray<uint>(12, Allocator.Persistent);
    103.         ENCODED_EDGE_OFFSETS.CopyFrom(ENCODED_EDGE_OFFSETS_ARRAY);
    104.  
    105.         ENCODED_EDGE_NODE_OFFSETS = new NativeArray<uint>(12, Allocator.Persistent);
    106.         ENCODED_EDGE_NODE_OFFSETS.CopyFrom(ENCODED_EDGE_NODE_OFFSETS_ARRAY);
    107.  
    108.         entityCommandBufferSystem = World.GetOrCreateSystem<EntityCommandBufferSystem>();
    109.     }
    110.  
    111.     [BurstCompile]
    112.     public struct ClearBuffersJob : IJob
    113.     {
    114.         public NativeHashMap<uint, Edge> activeEdges;
    115.         public NativeHashMap<uint, uint> activeVoxels;
    116.         public NativeHashMap<uint, uint> vertexIndices;
    117.  
    118.  
    119.         public NativeList<float3> vertices;
    120.         public NativeList<float3> normals;
    121.         public NativeList<int> triangles;
    122.  
    123.         public void Execute()
    124.         {
    125.             activeEdges.Clear();
    126.             activeVoxels.Clear();
    127.             vertices.Clear();
    128.             normals.Clear();
    129.             vertexIndices.Clear();
    130.             triangles.Clear();
    131.         }
    132.     }
    133.  
    134.  
    135.     //[BurstCompile]
    136.     public struct setMeshDataJob : IJob
    137.     {
    138.  
    139.      
    140.  
    141.  
    142.         public Entity chunk;
    143.  
    144.         public EntityCommandBuffer em;
    145.  
    146.         public MeshData meshData;
    147.  
    148.         public void Execute()
    149.         {
    150.            
    151.            
    152.  
    153.             em.AddSharedComponent(chunk, meshData);
    154.  
    155.            
    156.  
    157.         }
    158.     }
    159.  
    160.  
    161.  
    162.    
    163.     protected override JobHandle OnUpdate(JobHandle inputDeps)
    164.     {
    165.  
    166.         chunks = chunksQuery.ToEntityArray(Allocator.TempJob);
    167.  
    168.         if(chunks.Length == 0)
    169.         {
    170.             chunks.Dispose();
    171.             return inputDeps;
    172.         }
    173.  
    174.         chunk = chunks[0];
    175.         chunks.Dispose();
    176.         EntityManager.RemoveComponent<NeedsMeshing>(chunk);
    177.  
    178.         ChunkInfo chunkInfo = EntityManager.GetComponentData<ChunkInfo>(chunk);
    179.  
    180.  
    181.         MeshData meshData = new MeshData
    182.         {
    183.             vertices = new NativeList<float3>(64 * 64 * 64, Allocator.Persistent),
    184.             normals = new NativeList<float3>(64 * 64 * 64, Allocator.Persistent),
    185.             triangles = new NativeList<int>(64 * 64 * 64, Allocator.Persistent)
    186.         };
    187.  
    188.         //EntityManager.AddSharedComponentData(chunk, meshData);
    189.        
    190.  
    191.  
    192.         /*var ClearBuffers = new ClearBuffersJob()
    193.         {
    194.             activeEdges = activeEdges,
    195.             activeVoxels = activeVoxels,
    196.             vertexIndices = vertexIndices,
    197.             vertices = vertices,
    198.             normals = normals,
    199.             triangles = triangles
    200.  
    201.         };*/
    202.  
    203.         var FindActiveVoxels = new FindActiveVoxelsAndEdgesJobs() {
    204.             activeEdges = activeEdges.AsParallelWriter(),
    205.             activeVoxels = activeVoxels.AsParallelWriter(),
    206.             AXIS_OFFSET = AXIS_OFFSET,
    207.             EDGE_NODE_OFFSETS = EDGE_NODE_OFFSETS,
    208.             voxelData = EntityManager.GetBuffer<VoxelData>(chunk).Reinterpret<float>().ToNativeArray(Allocator.TempJob),
    209.             SizeX = chunkInfo.size.x,
    210.             SizeY = chunkInfo.size.y,
    211.         };
    212.  
    213.         var GenerateVertexData = new GenerateVertexDataJob
    214.         {
    215.             activeEdges = activeEdges,
    216.             activeVoxels = activeVoxels,
    217.             vertexIndices = vertexIndices,
    218.             vertices = meshData.vertices,
    219.             normals = meshData.normals,
    220.             ENCODED_EDGE_OFFSETS = ENCODED_EDGE_OFFSETS
    221.            
    222.         };
    223.  
    224.         var GenerateTriangleData = new GenerateTriangleDataJob
    225.         {
    226.             activeEdges = activeEdges,
    227.             vertexIndices = vertexIndices,
    228.             triangles = triangles,
    229.             ENCODED_EDGE_NODE_OFFSETS = ENCODED_EDGE_NODE_OFFSETS
    230.         };
    231.  
    232.         var setMeshData = new setMeshDataJob
    233.         {
    234.            
    235.             chunk = chunk,
    236.             em = entityCommandBufferSystem.CreateCommandBuffer(),
    237.             meshData = meshData
    238.         };
    239.  
    240.         //JobHandle clearBufferHandle = ClearBuffers.Schedule(inputDeps);
    241.         JobHandle FindActiveVoxelsHandle = FindActiveVoxels.Schedule(chunkInfo.size.x * chunkInfo.size.y * chunkInfo.size.z, 1, inputDeps);
    242.         JobHandle GenerateVertexDataHandle = GenerateVertexData.Schedule(FindActiveVoxelsHandle);
    243.         JobHandle GenerateTriangleDataHandle = GenerateTriangleData.Schedule(GenerateVertexDataHandle);
    244.         JobHandle setMeshDataHandle = setMeshData.Schedule(GenerateTriangleDataHandle);
    245.  
    246.         entityCommandBufferSystem.AddJobHandleForProducer(setMeshDataHandle);
    247.  
    248.  
    249.         return setMeshDataHandle;
    250.  
    251.  
    252.     }
    253.     protected override void OnDestroy()
    254.     {
    255.         activeEdges.Dispose();
    256.         activeVoxels.Dispose();
    257.         vertexIndices.Dispose();
    258.  
    259.         vertices.Dispose();
    260.         normals.Dispose();
    261.         triangles.Dispose();
    262.  
    263.         AXIS_OFFSET.Dispose();
    264.         EDGE_NODE_OFFSETS.Dispose();
    265.         ENCODED_EDGE_OFFSETS.Dispose();
    266.         ENCODED_EDGE_NODE_OFFSETS.Dispose();
    267.     }
    268. }
    269.  

    And here is the next system that then attempts to read from the ISharedComponentData:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4. using Unity.Entities;
    5. using Unity.Rendering;
    6.  
    7. public class MeshCreationSystem : ComponentSystem
    8. {
    9.    
    10.     protected override void OnCreate()
    11.     {
    12.     }
    13.  
    14.     protected override void OnUpdate()
    15.     {
    16.         Entities.WithAll<MeshData>().ForEach((Entity e, MeshData meshData) =>
    17.         {
    18.             RenderMesh renderMesh = new RenderMesh();
    19.  
    20.             Mesh mesh = new Mesh();
    21.  
    22.            
    23.  
    24.             mesh.SetVertices(meshData.vertices.AsArray());
    25.             mesh.SetNormals(meshData.normals.AsArray());
    26.             mesh.SetIndices(meshData.triangles.AsArray(), MeshTopology.Triangles, 0);
    27.  
    28.            
    29.  
    30.             EntityManager.AddSharedComponentData(e, renderMesh);
    31.             EntityManager.RemoveComponent<MeshData>(e);
    32.  
    33.         });
    34.  
    35.  
    36.     }
    37.  
    38.     protected override void OnDestroy()
    39.     {
    40.     }
    41.  
    42. }
    43.