Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question How to pass array of Native Arrays to the job?

Discussion in 'Entity Component System' started by Zylkowski_a, Sep 12, 2020.

  1. Zylkowski_a

    Zylkowski_a

    Joined:
    Jul 27, 2019
    Posts:
    157
    I need to pass array of Native Arrays to the job, is there any possibility to do it ( other than creating own native container)?
     
  2. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,010
    You can do it via constructor of struct you use for the job.
     
  3. Zylkowski_a

    Zylkowski_a

    Joined:
    Jul 27, 2019
    Posts:
    157
    That's not possible, it gives :
    InvalidOperationException: SampleJob.array is not a value type. Job structs may not contain any reference types.
     
  4. Joachim_Ante

    Joachim_Ante

    Unity Technologies

    Joined:
    Mar 16, 2005
    Posts:
    5,203
    You can use UnsafeList & friends if you are fine with writing unsafe code & not having the safety system cover your back.

    NativeContainers can't be nested. The job debugger safety system doesn't support arrays of containers.
     
  5. Zylkowski_a

    Zylkowski_a

    Joined:
    Jul 27, 2019
    Posts:
    157
    I can't nest Native containers in UnsafeList either.
     
  6. DreamingImLatios

    DreamingImLatios

    Joined:
    Jun 3, 2017
    Posts:
    3,984
    You can nest unsafe containers inside native containers, and you can nest unsafe containers inside unsafe containers. But you cannot nest native containers inside anything.
     
    charleshendry likes this.
  7. Zylkowski_a

    Zylkowski_a

    Joined:
    Jul 27, 2019
    Posts:
    157
    Ah okay, thank you!
     
  8. koirat

    koirat

    Joined:
    Jul 7, 2012
    Posts:
    2,010
    Sorry I have readen to fast and thought it is a beginner question. Good to know such a limitation exists.

    You may try to combine your arrays into one and have additional array with start positions and element counts.
     
    burningmime likes this.
  9. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    Yup; this is probably the best choice if it fits your algorithm/use case. You get fewer allocations, lower overhead, and better memory locality/access patterns. For example, here's how I'm stuffing some BlobArrays together:

    Code (CSharp):
    1.  
    2. // The source data (managed array of arrays)
    3. private HoleGeometry[] _data;
    4. private struct HoleGeometry
    5. {
    6.     public float2[] vertices;
    7.     public byte[] indices;
    8.     public bool showWallBottom;
    9. }
    10.  
    11. // The target data (blob arrays)
    12. internal struct Native
    13. {
    14.     public BlobArray<HoleInfo> info;
    15.     public BlobArray<float2> vertices;
    16.     public BlobArray<int> indices;
    17.  
    18.     public NativeArray<float2> getVertices(int holeId)
    19.     {
    20.         HoleInfo h = info[holeId];
    21.         return vertices.AsNativeSubArray(h.vertexOfs, h.vertexCount);
    22.     }
    23.  
    24.     public NativeArray<int> getIndices(int holeId)
    25.     {
    26.         HoleInfo h = info[holeId];
    27.         return indices.AsNativeSubArray(h.indexOfs, h.indexCount);
    28.     }
    29. }
    30.  
    31. // The conversion function
    32. internal void buildNativeData(ref Native n, ref BlobBuilder bb)
    33. {
    34.     // Count total number of vertices and indices
    35.     int totalVertices = 0, totalIndices = 0, totalHoles = _data.Length;
    36.     for(int i = 0; i < totalHoles; ++i)
    37.     {
    38.         HoleGeometry g = _data[i];
    39.         totalVertices += g.vertices.Length;
    40.         totalIndices += g.indices.Length;
    41.     }
    42.  
    43.     // Allocate appropriately sized arrays
    44.     BlobBuilderArray<HoleInfo> holes = bb.Allocate(ref n.info, totalHoles);
    45.     BlobBuilderArray<float2> vertices = bb.Allocate(ref n.vertices, totalVertices);
    46.     BlobBuilderArray<int> indices = bb.Allocate(ref n.indices, totalIndices);
    47.  
    48.     // Stuff data into those 3 arrays and store the offsets
    49.     int iVertex = 0; iIndex = 0;
    50.     for(int i = 0; i < totalHoles; ++i)
    51.     {
    52.         HoleGeometry g = _data[i];
    53.         holes[i] = new HoleInfo {
    54.             indexOfs = iIndex,
    55.             indexCount = g.indices.Length,
    56.             vertexOfs = iVertex,
    57.             vertexCount = g.vertices.Length,
    58.             showWallBottom = g.showWallBottom };
    59.         for(int j = 0; j < g.vertices.Length; ++j)
    60.             vertices[j + iVertex] = g.vertices[j];
    61.         for(int j = 0; j < g.indices.Length; ++j)
    62.             indices[j + iIndex] = g.indices[j];
    63.         iVertex += g.vertices.Length;
    64.         iIndex += g.indices.Length;
    65.     }
    66. }