protected override void OnUpdate()
    {
        NativeQueue <TileData> nativeQueue = new NativeQueue <TileData>(Allocator.TempJob);

        CopyTileJob copyTileJob = new CopyTileJob {
            nativeQueue = nativeQueue.ToConcurrent()
        };
        JobHandle jobHandle = copyTileJob.Schedule(this);

        jobHandle.Complete();

        NativeArray <TileData> nativeArray = new NativeArray <TileData>(nativeQueue.Count, Allocator.TempJob);

        NativeQueueToArrayJob nativeQueueToArrayJob = new NativeQueueToArrayJob {
            nativeQueue = nativeQueue,
            nativeArray = nativeArray,
        };

        jobHandle = nativeQueueToArrayJob.Schedule();
        jobHandle.Complete();

        nativeQueue.Dispose();

        var camera = Camera.main;

        //if (camera != null && Input.GetMouseButtonDown(0))
        {
            var mousePosition = Input.mousePosition;
            var cameraRay     = camera.ScreenPointToRay(mousePosition);

            Entities.WithAll <HexTileHightlightComponent>().ForEach((Entity entity) => {
                PostUpdateCommands.RemoveComponent <HexTileHightlightComponent>(entity);
            });
            var deltaTime = Time.deltaTime;
            if (UnityEngine.Physics.Raycast(cameraRay, out var closestHit, float.PositiveInfinity))
            {
                Vector3   mapPos = new Vector3(closestHit.point.x, 0, closestHit.point.z);
                CubeIndex index  = HexUtils.FromPosition(mapPos, Bootstrap.Defines.TileRadius);
                Debug.DrawLine(Vector3.zero, closestHit.point, Color.red, 2.5f);
                for (int i = 0; i < nativeArray.Length; i++)
                {
                    if (nativeArray[i].index.Equals(index))
                    {
                        PostUpdateCommands.AddComponent(nativeArray[i].entity, new HexTileHightlightComponent());
                        break;
                    }
                }
            }
        }

        nativeArray.Dispose();
    }
Exemple #2
0
    protected override void OnUpdate()
    {
        for (int i = 0; i < POSITION_SLICES; i++)
        {
            ClearQueueJob clearQueueJob = new ClearQueueJob {
                nativeQueue = nativeQueueArray[i]
            };
            jobHandleArray[i] = clearQueueJob.Schedule();
        }

        JobHandle.CompleteAll(jobHandleArray);

        Camera camera          = Camera.main;
        float  cameraWidth     = camera.aspect * camera.orthographicSize;
        float3 cameraPosition  = camera.transform.position;
        float  marginX         = cameraWidth / 10f;
        float  xMin            = cameraPosition.x - cameraWidth - marginX;
        float  xMax            = cameraPosition.x + cameraWidth + marginX;
        float  cameraSliceSize = camera.orthographicSize * 2f / POSITION_SLICES;
        float  yBottom         = cameraPosition.y - camera.orthographicSize; // Bottom cull position
        float  yTop_1          = cameraPosition.y + camera.orthographicSize; // Top most cull position

        float yTop_2  = yTop_1 - cameraSliceSize * 1f;
        float yTop_3  = yTop_1 - cameraSliceSize * 2f;
        float yTop_4  = yTop_1 - cameraSliceSize * 3f;
        float yTop_5  = yTop_1 - cameraSliceSize * 4f;
        float yTop_6  = yTop_1 - cameraSliceSize * 5f;
        float yTop_7  = yTop_1 - cameraSliceSize * 6f;
        float yTop_8  = yTop_1 - cameraSliceSize * 7f;
        float yTop_9  = yTop_1 - cameraSliceSize * 8f;
        float yTop_10 = yTop_1 - cameraSliceSize * 9f;
        float yTop_11 = yTop_1 - cameraSliceSize * 10f;
        float yTop_12 = yTop_1 - cameraSliceSize * 11f;
        float yTop_13 = yTop_1 - cameraSliceSize * 12f;
        float yTop_14 = yTop_1 - cameraSliceSize * 13f;
        float yTop_15 = yTop_1 - cameraSliceSize * 14f;
        float yTop_16 = yTop_1 - cameraSliceSize * 15f;
        float yTop_17 = yTop_1 - cameraSliceSize * 16f;
        float yTop_18 = yTop_1 - cameraSliceSize * 17f;
        float yTop_19 = yTop_1 - cameraSliceSize * 18f;
        float yTop_20 = yTop_1 - cameraSliceSize * 19f;

        float marginY = camera.orthographicSize / 10f;

        yTop_1  += marginY;
        yBottom -= marginY;

        CullAndSortNativeQueueJob cullAndSortNativeQueueJob = new CullAndSortNativeQueueJob {
            xMin    = xMin,
            xMax    = xMax,
            yBottom = yBottom,

            yTop_1  = yTop_1,
            yTop_2  = yTop_2,
            yTop_3  = yTop_3,
            yTop_4  = yTop_4,
            yTop_5  = yTop_5,
            yTop_6  = yTop_6,
            yTop_7  = yTop_7,
            yTop_8  = yTop_8,
            yTop_9  = yTop_9,
            yTop_10 = yTop_10,
            yTop_11 = yTop_11,
            yTop_12 = yTop_12,
            yTop_13 = yTop_13,
            yTop_14 = yTop_14,
            yTop_15 = yTop_15,
            yTop_16 = yTop_16,
            yTop_17 = yTop_17,
            yTop_18 = yTop_18,
            yTop_19 = yTop_19,
            yTop_20 = yTop_20,

            nativeQueue_1  = nativeQueueArray[0].AsParallelWriter(),
            nativeQueue_2  = nativeQueueArray[1].AsParallelWriter(),
            nativeQueue_3  = nativeQueueArray[2].AsParallelWriter(),
            nativeQueue_4  = nativeQueueArray[3].AsParallelWriter(),
            nativeQueue_5  = nativeQueueArray[4].AsParallelWriter(),
            nativeQueue_6  = nativeQueueArray[5].AsParallelWriter(),
            nativeQueue_7  = nativeQueueArray[6].AsParallelWriter(),
            nativeQueue_8  = nativeQueueArray[7].AsParallelWriter(),
            nativeQueue_9  = nativeQueueArray[8].AsParallelWriter(),
            nativeQueue_10 = nativeQueueArray[9].AsParallelWriter(),
            nativeQueue_11 = nativeQueueArray[10].AsParallelWriter(),
            nativeQueue_12 = nativeQueueArray[11].AsParallelWriter(),
            nativeQueue_13 = nativeQueueArray[12].AsParallelWriter(),
            nativeQueue_14 = nativeQueueArray[13].AsParallelWriter(),
            nativeQueue_15 = nativeQueueArray[14].AsParallelWriter(),
            nativeQueue_16 = nativeQueueArray[15].AsParallelWriter(),
            nativeQueue_17 = nativeQueueArray[16].AsParallelWriter(),
            nativeQueue_18 = nativeQueueArray[17].AsParallelWriter(),
            nativeQueue_19 = nativeQueueArray[18].AsParallelWriter(),
            nativeQueue_20 = nativeQueueArray[19].AsParallelWriter()
        };
        JobHandle cullAndSortNativeQueueJobHandle = cullAndSortNativeQueueJob.Schedule(this);

        cullAndSortNativeQueueJobHandle.Complete();

        int visibleEntityTotal = 0;

        for (int i = 0; i < POSITION_SLICES; i++)
        {
            visibleEntityTotal += nativeQueueArray[i].Count;
        }


        for (int i = 0; i < POSITION_SLICES; i++)
        {
            NativeArray <RenderData> nativeArray = new NativeArray <RenderData>(nativeQueueArray[i].Count, Allocator.TempJob);
            nativeArrayArray[i] = nativeArray;
        }


        for (int i = 0; i < POSITION_SLICES; i++)
        {
            NativeQueueToArrayJob nativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = nativeQueueArray[i],
                nativeArray = nativeArrayArray[i],
            };
            jobHandleArray[i] = nativeQueueToArrayJob.Schedule();
        }

        JobHandle.CompleteAll(jobHandleArray);

        // Sort by position
        for (int i = 0; i < POSITION_SLICES; i++)
        {
            SortByPositionJob sortByPositionJob = new SortByPositionJob {
                sortArray = nativeArrayArray[i],
                comparer  = positionComparer
            };
            jobHandleArray[i] = sortByPositionJob.Schedule();
        }

        JobHandle.CompleteAll(jobHandleArray);


        // Fill up individual Arrays
        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

        int startingIndex = 0;

        for (int i = 0; i < POSITION_SLICES; i++)
        {
            //if (i != 4) continue;
            FillArraysParallelJob fillArraysParallelJob = new FillArraysParallelJob {
                nativeArray   = nativeArrayArray[i],
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                startingIndex = startingIndex
            };
            startingIndex    += nativeArrayArray[i].Length;
            jobHandleArray[i] = fillArraysParallelJob.Schedule(nativeArrayArray[i].Length, 10);
        }

        JobHandle.CompleteAll(jobHandleArray);

        //jobHandleArray.Dispose();

        for (int i = 0; i < POSITION_SLICES; i++)
        {
            nativeArrayArray[i].Dispose();
        }


        // Slice Arrays and Draw
        InitDrawMeshInstancedSlicedData();
        for (int i = 0; i < visibleEntityTotal; i += DRAW_MESH_INSTANCED_SLICE_COUNT)
        {
            int sliceSize = math.min(visibleEntityTotal - i, DRAW_MESH_INSTANCED_SLICE_COUNT);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

            materialPropertyBlock.SetVectorArray(shaderMainTexUVid, uvInstancedArray);

            Graphics.DrawMeshInstanced(mesh, 0, material, matrixInstancedArray, sliceSize, materialPropertyBlock);
        }

        matrixArray.Dispose();
        uvArray.Dispose();
    }
    protected override void OnUpdate()
    {
        EntityQuery query = GetEntityQuery(typeof(SpriteSheetAnimation_Data), typeof(Translation));
        NativeArray <SpriteSheetAnimation_Data> animDataArray = query.ToComponentDataArray <SpriteSheetAnimation_Data>(Allocator.TempJob);
        NativeArray <Translation> translations = query.ToComponentDataArray <Translation>(Allocator.TempJob);

        NativeQueue <RenderData> nativeQueue_1 = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> nativeQueue_2 = new NativeQueue <RenderData>(Allocator.TempJob);

        Camera camera         = Camera.main;
        float3 cameraPosition = camera.transform.position;
        float  yBottom        = cameraPosition.y - camera.orthographicSize;
        float  yTop_1         = cameraPosition.y + camera.orthographicSize;
        float  yTop_2         = cameraPosition.y;

        CullAndSortJob job = new CullAndSortJob()
        {
            yBottom       = yBottom,
            yTop_1        = yTop_1,
            yTop_2        = yTop_2,
            nativeQueue_1 = nativeQueue_1.AsParallelWriter(),
            nativeQueue_2 = nativeQueue_2.AsParallelWriter()
        };

        JobHandle handle = job.Schedule(this);

        handle.Complete();

        NativeArray <RenderData> nativeArray_1 = new NativeArray <RenderData>(nativeQueue_1.Count, Allocator.Temp);
        NativeArray <RenderData> nativeArray_2 = new NativeArray <RenderData>(nativeQueue_2.Count, Allocator.Temp);

        NativeQueueToArrayJob queueToArrayJob_1 = new NativeQueueToArrayJob()
        {
            array = nativeArray_1,
            queue = nativeQueue_1
        };

        NativeQueueToArrayJob queueToArrayJob_2 = new NativeQueueToArrayJob()
        {
            array = nativeArray_2,
            queue = nativeQueue_2
        };

        NativeArray <JobHandle> handles = new NativeArray <JobHandle>(2, Allocator.Temp);

        handles[0] = queueToArrayJob_1.Schedule();
        handles[1] = queueToArrayJob_2.Schedule();

        JobHandle.CompleteAll(handles);

        nativeQueue_1.Dispose();
        nativeQueue_2.Dispose();

        SortByPossitionJob sortByPossitionJob_1 = new SortByPossitionJob()
        {
            sortArray = nativeArray_1
        };

        SortByPossitionJob sortByPossitionJob_2 = new SortByPossitionJob()
        {
            sortArray = nativeArray_2
        };

        handles[0] = sortByPossitionJob_1.Schedule();
        handles[1] = sortByPossitionJob_2.Schedule();

        JobHandle.CompleteAll(handles);

        int visibleEntities = nativeArray_1.Length + nativeArray_2.Length;
        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntities, Allocator.Temp);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntities, Allocator.Temp);

        Matrix4x4[] matrices = new Matrix4x4[visibleEntities];
        Vector4[]   uvs      = new Vector4[visibleEntities];

        FillArraysParallelJob fillArraysJob_1 = new FillArraysParallelJob()
        {
            nativeArray = nativeArray_1,
            matrixArray = matrixArray,
            uvArray     = uvArray,
            startIndex  = 0
        };

        FillArraysParallelJob fillArraysJob_2 = new FillArraysParallelJob()
        {
            nativeArray = nativeArray_2,
            matrixArray = matrixArray,
            uvArray     = uvArray,
            startIndex  = nativeArray_1.Length
        };

        handles[0] = fillArraysJob_1.Schedule(nativeArray_1.Length, 10);
        handles[0] = fillArraysJob_2.Schedule(nativeArray_2.Length, 10);
        JobHandle.CompleteAll(handles);

        int sliceCount = 1023;

        for (int i = 0; i < animDataArray.Length; i += sliceCount)
        {
            int sliceSize = math.min(animDataArray.Length - i, sliceCount);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrices, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvs, 0, sliceSize);

            propertyBlock.SetVectorArray(shaderPropertyID, uvs);

            Graphics.DrawMeshInstanced(
                mesh,
                0,
                material,
                matrices,
                sliceSize,
                propertyBlock
                );
        }

        matrixArray.Dispose();
        uvArray.Dispose();
        animDataArray.Dispose();
        translations.Dispose();
    }
    protected override void OnUpdate()
    {
        NativeQueue <RenderData> terrain0NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> terrain1NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);

        CopyTileJob copyTileJob = new CopyTileJob
        {
            terrain0NativeQueue = terrain0NativeQueue.AsParallelWriter(),
            terrain1NativeQueue = terrain1NativeQueue.AsParallelWriter()
        };
        JobHandle jobHandle = copyTileJob.Schedule(this);

        jobHandle.Complete();

        NativeArray <RenderData> terrain0NativeArray = new NativeArray <RenderData>(terrain0NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> terrain1NativeArray = new NativeArray <RenderData>(terrain1NativeQueue.Count, Allocator.TempJob);

        NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(2, Allocator.TempJob);

        NativeQueueToArrayJob terrain0NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = terrain0NativeQueue,
            nativeArray = terrain0NativeArray,
        };

        jobHandleArray[0] = terrain0NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob terrain1NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = terrain1NativeQueue,
            nativeArray = terrain1NativeArray,
        };

        jobHandleArray[1] = terrain1NativeQueueToArrayJob.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        terrain0NativeQueue.Dispose();
        terrain1NativeQueue.Dispose();

        int visibleTileTotal = terrain0NativeArray.Length + terrain1NativeArray.Length;

        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleTileTotal, Allocator.TempJob);

        FillArrayForParalleJob fillArrayForParalleJob_0 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = terrain0NativeArray,
            startingIndex = 0
        };

        jobHandleArray[0] = fillArrayForParalleJob_0.Schedule(terrain0NativeArray.Length, 10);

        FillArrayForParalleJob fillArrayForParalleJob_1 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = terrain1NativeArray,
            startingIndex = terrain0NativeArray.Length
        };

        jobHandleArray[1] = fillArrayForParalleJob_1.Schedule(terrain1NativeArray.Length, 10);

        JobHandle.CompleteAll(jobHandleArray);

        int sliceCount = matrixInstanceArray.Length;
        int off        = 0;

        //for(int i=0;i< nativeArray.Length;i+= sliceCount)
        while (off < visibleTileTotal)
        {
            float tilePick  = off < terrain0NativeArray.Length ? 0 : 0.34f;
            int   sliceSize = math.min(visibleTileTotal - off, sliceCount);
            if (off < terrain0NativeArray.Length && off + sliceSize >= terrain0NativeArray.Length)
            {
                sliceSize = terrain0NativeArray.Length - off;
            }
            NativeArray <Matrix4x4> .Copy(matrixArray, off, matrixInstanceArray, 0, sliceSize);

            Graphics.DrawMeshInstanced(
                Bootstrap.Defines.tileCollections.Pick(tilePick),
                0,
                Bootstrap.Defines.TileMaterial,
                matrixInstanceArray,
                sliceSize);

            off += sliceSize;
        }

        matrixArray.Dispose();
        terrain0NativeArray.Dispose();
        terrain1NativeArray.Dispose();
        jobHandleArray.Dispose();
    }
    protected override void OnUpdate()
    {
        NativeQueue <RenderData> nativeQueue_1 = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> nativeQueue_2 = new NativeQueue <RenderData>(Allocator.TempJob);

        Camera camera         = Camera.main;
        float3 cameraPosition = camera.transform.position;
        float  yBottom        = cameraPosition.y - camera.orthographicSize;
        float  yTop_1         = cameraPosition.y + camera.orthographicSize;
        float  yTop_2         = cameraPosition.y + 0f;

        CullAndSortJob cullAndSortJob = new CullAndSortJob {
            yBottom = yBottom,
            yTop_1  = yTop_1,
            yTop_2  = yTop_2,

            nativeQueue_1 = nativeQueue_1.ToConcurrent(),
            nativeQueue_2 = nativeQueue_2.ToConcurrent(),
        };
        JobHandle jobHandle = cullAndSortJob.Schedule(this);

        jobHandle.Complete();

        // Convert Queues into Arrays for Sorting
        NativeArray <RenderData> nativeArray_1 = new NativeArray <RenderData>(nativeQueue_1.Count, Allocator.TempJob);
        NativeArray <RenderData> nativeArray_2 = new NativeArray <RenderData>(nativeQueue_2.Count, Allocator.TempJob);

        NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(2, Allocator.TempJob);

        NativeQueueToArrayJob nativeQueueToArrayJob_1 = new NativeQueueToArrayJob {
            nativeQueue = nativeQueue_1,
            nativeArray = nativeArray_1,
        };

        jobHandleArray[0] = nativeQueueToArrayJob_1.Schedule();

        NativeQueueToArrayJob nativeQueueToArrayJob_2 = new NativeQueueToArrayJob {
            nativeQueue = nativeQueue_2,
            nativeArray = nativeArray_2,
        };

        jobHandleArray[1] = nativeQueueToArrayJob_2.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        nativeQueue_1.Dispose();
        nativeQueue_2.Dispose();

        // Sort arrays by position
        SortByPositionJob sortByPositionJob_1 = new SortByPositionJob {
            sortArray = nativeArray_1,
        };

        jobHandleArray[0] = sortByPositionJob_1.Schedule();

        SortByPositionJob sortByPositionJob_2 = new SortByPositionJob {
            sortArray = nativeArray_2,
        };

        jobHandleArray[1] = sortByPositionJob_2.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        int visibleEntityTotal = nativeArray_1.Length + nativeArray_2.Length;

        // Grab sliced arrays and merge them all into one
        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleEntityTotal, Allocator.TempJob);
        NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleEntityTotal, Allocator.TempJob);

        FillArraysParallelJob fillArraysParallelJob_1 = new FillArraysParallelJob {
            nativeArray   = nativeArray_1,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = 0,
        };

        jobHandleArray[0] = fillArraysParallelJob_1.Schedule(nativeArray_1.Length, 10);

        FillArraysParallelJob fillArraysParallelJob_2 = new FillArraysParallelJob {
            nativeArray   = nativeArray_2,
            matrixArray   = matrixArray,
            uvArray       = uvArray,
            startingIndex = nativeArray_1.Length,
        };

        jobHandleArray[1] = fillArraysParallelJob_2.Schedule(nativeArray_2.Length, 10);

        JobHandle.CompleteAll(jobHandleArray);

        jobHandleArray.Dispose();

        nativeArray_1.Dispose();
        nativeArray_2.Dispose();

        // Draw
        MaterialPropertyBlock materialPropertyBlock = new MaterialPropertyBlock();

        Vector4[] uv               = new Vector4[1];
        Mesh      quadMesh         = GameController.Instance.Mesh;
        Material  material         = GameController.Instance.Material;
        int       shaderPropertyId = Shader.PropertyToID("_MainTex_UV");

        int sliceCount = 1023;

        Matrix4x4[] matrixInstancedArray = new Matrix4x4[sliceCount];
        Vector4[]   uvInstancedArray     = new Vector4[sliceCount];

        for (int i = 0; i < visibleEntityTotal; i += sliceCount)
        {
            int sliceSize = math.min(visibleEntityTotal - i, sliceCount);

            NativeArray <Matrix4x4> .Copy(matrixArray, i, matrixInstancedArray, 0, sliceSize);

            NativeArray <Vector4> .Copy(uvArray, i, uvInstancedArray, 0, sliceSize);

            materialPropertyBlock.SetVectorArray(shaderPropertyId, uvInstancedArray);

            Graphics.DrawMeshInstanced(
                quadMesh,
                0,
                material,
                matrixInstancedArray,
                sliceSize,
                materialPropertyBlock
                );
        }

        matrixArray.Dispose();
        uvArray.Dispose();
    }
Exemple #6
0
    protected override void OnUpdate()
    {
        NativeQueue <RenderData> node0NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> node1NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> node2NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> node3NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> node4NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> node5NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);
        NativeQueue <RenderData> node6NativeQueue = new NativeQueue <RenderData>(Allocator.TempJob);

        CopyTileJob copyTileJob = new CopyTileJob
        {
            node0NativeQueue = node0NativeQueue.ToConcurrent(),
            node1NativeQueue = node1NativeQueue.ToConcurrent(),
            node2NativeQueue = node2NativeQueue.ToConcurrent(),
            node3NativeQueue = node3NativeQueue.ToConcurrent(),
            node4NativeQueue = node4NativeQueue.ToConcurrent(),
            node5NativeQueue = node5NativeQueue.ToConcurrent(),
            node6NativeQueue = node6NativeQueue.ToConcurrent()
        };
        JobHandle jobHandle = copyTileJob.Schedule(this);

        jobHandle.Complete();

        NativeArray <RenderData> node0NativeArray = new NativeArray <RenderData>(node0NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> node1NativeArray = new NativeArray <RenderData>(node1NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> node2NativeArray = new NativeArray <RenderData>(node1NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> node3NativeArray = new NativeArray <RenderData>(node1NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> node4NativeArray = new NativeArray <RenderData>(node1NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> node5NativeArray = new NativeArray <RenderData>(node1NativeQueue.Count, Allocator.TempJob);
        NativeArray <RenderData> node6NativeArray = new NativeArray <RenderData>(node1NativeQueue.Count, Allocator.TempJob);

        NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(7, Allocator.TempJob);

        NativeQueueToArrayJob node0NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node0NativeQueue,
            nativeArray = node0NativeArray,
        };

        jobHandleArray[0] = node0NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob node1NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node1NativeQueue,
            nativeArray = node1NativeArray,
        };

        jobHandleArray[1] = node1NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob node2NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node2NativeQueue,
            nativeArray = node2NativeArray,
        };

        jobHandleArray[2] = node2NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob node3NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node3NativeQueue,
            nativeArray = node3NativeArray,
        };

        jobHandleArray[3] = node3NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob node4NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node4NativeQueue,
            nativeArray = node4NativeArray,
        };

        jobHandleArray[4] = node4NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob node5NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node5NativeQueue,
            nativeArray = node5NativeArray,
        };

        jobHandleArray[5] = node5NativeQueueToArrayJob.Schedule();

        NativeQueueToArrayJob node6NativeQueueToArrayJob = new NativeQueueToArrayJob
        {
            nativeQueue = node6NativeQueue,
            nativeArray = node6NativeArray,
        };

        jobHandleArray[6] = node6NativeQueueToArrayJob.Schedule();

        JobHandle.CompleteAll(jobHandleArray);

        node0NativeQueue.Dispose();
        node1NativeQueue.Dispose();
        node2NativeQueue.Dispose();
        node3NativeQueue.Dispose();
        node4NativeQueue.Dispose();
        node5NativeQueue.Dispose();
        node6NativeQueue.Dispose();

        int visibleTileTotal = node0NativeArray.Length + node1NativeArray.Length;

        NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleTileTotal, Allocator.TempJob);

        int startingIndex = 0;
        FillArrayForParalleJob fillArrayForParalleJob_0 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node0NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[0] = fillArrayForParalleJob_0.Schedule(node0NativeArray.Length, 10);
        startingIndex    += node0NativeArray.Length;

        FillArrayForParalleJob fillArrayForParalleJob_1 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node1NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[1] = fillArrayForParalleJob_1.Schedule(node1NativeArray.Length, 10);
        startingIndex    += node1NativeArray.Length;

        FillArrayForParalleJob fillArrayForParalleJob_2 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node2NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[2] = fillArrayForParalleJob_2.Schedule(node1NativeArray.Length, 10);
        startingIndex    += node2NativeArray.Length;

        FillArrayForParalleJob fillArrayForParalleJob_3 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node1NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[3] = fillArrayForParalleJob_3.Schedule(node3NativeArray.Length, 10);
        startingIndex    += node3NativeArray.Length;

        FillArrayForParalleJob fillArrayForParalleJob_4 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node4NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[4] = fillArrayForParalleJob_4.Schedule(node4NativeArray.Length, 10);
        startingIndex    += node4NativeArray.Length;

        FillArrayForParalleJob fillArrayForParalleJob_5 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node5NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[5] = fillArrayForParalleJob_5.Schedule(node5NativeArray.Length, 10);
        startingIndex    += node5NativeArray.Length;

        FillArrayForParalleJob fillArrayForParalleJob_6 = new FillArrayForParalleJob
        {
            matrixArray   = matrixArray,
            nativeArray   = node6NativeArray,
            startingIndex = startingIndex
        };

        jobHandleArray[6] = fillArrayForParalleJob_6.Schedule(node6NativeArray.Length, 10);
        startingIndex    += node6NativeArray.Length;

        JobHandle.CompleteAll(jobHandleArray);

        int sliceCount = 1023;

        Matrix4x4[] matrixInstanceArray = new Matrix4x4[1023];
        int         off = 0;

        //while (off < visibleTileTotal)
        //{
        //    int tilePick = off < node0NativeArray.Length ? 0 : 0.34f;
        //    int sliceSize = math.min(visibleTileTotal - off, sliceCount);
        //    if (off < node0NativeArray.Length && off + sliceSize >= node0NativeArray.Length)
        //    {
        //        sliceSize = node0NativeArray.Length - off;
        //    }
        //    NativeArray<Matrix4x4>.Copy(matrixArray, off, matrixInstanceArray, 0, sliceSize);

        //    Graphics.DrawMeshInstanced(
        //        Bootstrap.Defines.ResourceNodesPrefab[tilePick].mesh,
        //        0,
        //        Bootstrap.Defines.ResourceNodesPrefab[tilePick].material,
        //        matrixInstanceArray,
        //        sliceSize);

        //    off += sliceSize;
        //}

        matrixArray.Dispose();
        node0NativeArray.Dispose();
        node1NativeArray.Dispose();
        node2NativeArray.Dispose();
        node3NativeArray.Dispose();
        node4NativeArray.Dispose();
        node5NativeArray.Dispose();
        node6NativeArray.Dispose();
        jobHandleArray.Dispose();
    }
    protected override void OnUpdate()
    {
        //Debug.Log(sheet0NativeQueue.Count);
        bool useQuadrantSystem = Testing.Instance.useQuadrantSystem;
        bool sortSprite        = Testing.Instance.sortSprite;

        if (useQuadrantSystem)
        {
            #region useQuadrantSystem
            NativeQueue <SpriteSheetAnimationComponent> node0NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node1NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node2NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node3NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node4NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node5NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node6NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node7NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            NativeQueue <SpriteSheetAnimationComponent> node8NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);

            CopySpriteMultiGroupJob copyTileMultiJob = new CopySpriteMultiGroupJob {
                sheet0NativeQueue = node0NativeQueue.AsParallelWriter(),
                sheet1NativeQueue = node1NativeQueue.AsParallelWriter(),
                sheet2NativeQueue = node2NativeQueue.AsParallelWriter(),
                sheet3NativeQueue = node3NativeQueue.AsParallelWriter(),
                sheet4NativeQueue = node4NativeQueue.AsParallelWriter(),
                sheet5NativeQueue = node5NativeQueue.AsParallelWriter(),
                sheet6NativeQueue = node6NativeQueue.AsParallelWriter(),
                sheet7NativeQueue = node7NativeQueue.AsParallelWriter(),
                sheet8NativeQueue = node8NativeQueue.AsParallelWriter()
            };
            JobHandle jobHandle = copyTileMultiJob.Schedule(this);
            jobHandle.Complete();

            NativeArray <SpriteSheetAnimationComponent> node0NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node0NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node1NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node1NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node2NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node2NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node3NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node3NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node4NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node4NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node5NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node5NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node6NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node6NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node7NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node7NativeQueue.Count, Allocator.TempJob);
            NativeArray <SpriteSheetAnimationComponent> node8NativeArray = new NativeArray <SpriteSheetAnimationComponent>(node8NativeQueue.Count, Allocator.TempJob);

            NativeArray <JobHandle> jobHandleArray = new NativeArray <JobHandle>(9, Allocator.TempJob);

            NativeQueueToArrayJob node0NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node0NativeQueue,
                nativeArray = node0NativeArray,
            };
            jobHandleArray[0] = node0NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node1NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node1NativeQueue,
                nativeArray = node1NativeArray,
            };
            jobHandleArray[1] = node1NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node2NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node2NativeQueue,
                nativeArray = node2NativeArray,
            };
            jobHandleArray[2] = node2NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node3NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node3NativeQueue,
                nativeArray = node3NativeArray,
            };
            jobHandleArray[3] = node3NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node4NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node4NativeQueue,
                nativeArray = node4NativeArray,
            };
            jobHandleArray[4] = node4NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node5NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node5NativeQueue,
                nativeArray = node5NativeArray,
            };
            jobHandleArray[5] = node5NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node6NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node6NativeQueue,
                nativeArray = node6NativeArray,
            };
            jobHandleArray[6] = node6NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node7NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node7NativeQueue,
                nativeArray = node7NativeArray,
            };
            jobHandleArray[7] = node7NativeQueueToArrayJob.Schedule();

            NativeQueueToArrayJob node8NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = node8NativeQueue,
                nativeArray = node8NativeArray,
            };
            jobHandleArray[8] = node8NativeQueueToArrayJob.Schedule();

            JobHandle.CompleteAll(jobHandleArray);

            node0NativeQueue.Dispose();
            node1NativeQueue.Dispose();
            node2NativeQueue.Dispose();
            node3NativeQueue.Dispose();
            node4NativeQueue.Dispose();
            node5NativeQueue.Dispose();
            node6NativeQueue.Dispose();
            node7NativeQueue.Dispose();
            node8NativeQueue.Dispose();

            if (sortSprite)
            {
                SortLayerJob sortLayer0Job = new SortLayerJob {
                    sortArray = node0NativeArray
                };
                jobHandleArray[0] = sortLayer0Job.Schedule();

                SortLayerJob sortLayer1Job = new SortLayerJob {
                    sortArray = node1NativeArray
                };
                jobHandleArray[1] = sortLayer1Job.Schedule();

                SortLayerJob sortLayer2Job = new SortLayerJob {
                    sortArray = node2NativeArray
                };
                jobHandleArray[2] = sortLayer2Job.Schedule();

                SortLayerJob sortLayer3Job = new SortLayerJob {
                    sortArray = node3NativeArray
                };
                jobHandleArray[3] = sortLayer3Job.Schedule();

                SortLayerJob sortLayer4Job = new SortLayerJob {
                    sortArray = node4NativeArray
                };
                jobHandleArray[4] = sortLayer4Job.Schedule();

                SortLayerJob sortLayer5Job = new SortLayerJob {
                    sortArray = node5NativeArray
                };
                jobHandleArray[5] = sortLayer5Job.Schedule();

                SortLayerJob sortLayer6Job = new SortLayerJob {
                    sortArray = node6NativeArray
                };
                jobHandleArray[6] = sortLayer6Job.Schedule();

                SortLayerJob sortLayer7Job = new SortLayerJob {
                    sortArray = node7NativeArray
                };
                jobHandleArray[7] = sortLayer7Job.Schedule();

                SortLayerJob sortLayer8Job = new SortLayerJob {
                    sortArray = node8NativeArray
                };
                jobHandleArray[8] = sortLayer8Job.Schedule();

                JobHandle.CompleteAll(jobHandleArray);
            }
            int visibleTileTotal = node0NativeArray.Length +
                                   node1NativeArray.Length +
                                   node2NativeArray.Length +
                                   node3NativeArray.Length +
                                   node4NativeArray.Length +
                                   node5NativeArray.Length +
                                   node6NativeArray.Length +
                                   node7NativeArray.Length +
                                   node8NativeArray.Length
            ;

            NativeArray <Matrix4x4> matrixArray = new NativeArray <Matrix4x4>(visibleTileTotal, Allocator.TempJob);
            NativeArray <Vector4>   uvArray     = new NativeArray <Vector4>(visibleTileTotal, Allocator.TempJob);
            NativeArray <int>       matIdArray  = new NativeArray <int>(visibleTileTotal, Allocator.TempJob);

            int startingIndex = 0;
            FillArrayForParalleJob fillArrayForParalleJob_0 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node0NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[0] = fillArrayForParalleJob_0.Schedule(node0NativeArray.Length, 10);
            startingIndex    += node0NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_1 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node1NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[1] = fillArrayForParalleJob_1.Schedule(node1NativeArray.Length, 10);
            startingIndex    += node1NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_2 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node2NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[2] = fillArrayForParalleJob_2.Schedule(node2NativeArray.Length, 10);
            startingIndex    += node2NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_3 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node3NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[3] = fillArrayForParalleJob_3.Schedule(node3NativeArray.Length, 10);
            startingIndex    += node3NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_4 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node4NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[4] = fillArrayForParalleJob_4.Schedule(node4NativeArray.Length, 10);
            startingIndex    += node4NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_5 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node5NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[5] = fillArrayForParalleJob_5.Schedule(node5NativeArray.Length, 10);
            startingIndex    += node5NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_6 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node6NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[6] = fillArrayForParalleJob_6.Schedule(node6NativeArray.Length, 10);
            startingIndex    += node6NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_7 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node7NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[7] = fillArrayForParalleJob_7.Schedule(node7NativeArray.Length, 10);
            startingIndex    += node7NativeArray.Length;

            FillArrayForParalleJob fillArrayForParalleJob_8 = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = node8NativeArray,
                startingIndex = startingIndex
            };
            jobHandleArray[8] = fillArrayForParalleJob_8.Schedule(node8NativeArray.Length, 10);
            startingIndex    += node8NativeArray.Length;

            JobHandle.CompleteAll(jobHandleArray);

            int sliceCount = matrixInstanceArray.Length;
            int off        = 0;
            while (off < visibleTileTotal)
            {
                int sheetId   = matIdArray[off];
                int sliceSize = 0;
                while (off + sliceSize < visibleTileTotal && sliceSize < sliceCount)
                {
                    if (matIdArray[off + sliceSize] != sheetId)
                    {
                        break;
                    }
                    sliceSize++;
                }

                NativeArray <Matrix4x4> .Copy(matrixArray, off, matrixInstanceArray, 0, sliceSize);

                NativeArray <Vector4> .Copy(uvArray, off, uvInstanceArray, 0, sliceSize);

                materialPropertyBlock.SetVectorArray(sharedPropertyId, uvInstanceArray);

                Graphics.DrawMeshInstanced(
                    Testing.Instance.mesh,
                    0,
                    GetMaterial(sheetId),
                    matrixInstanceArray,
                    sliceSize,
                    materialPropertyBlock
                    );

                off += sliceSize;
            }

            matrixArray.Dispose();
            uvArray.Dispose();
            matIdArray.Dispose();

            node0NativeArray.Dispose();
            node1NativeArray.Dispose();
            node2NativeArray.Dispose();
            node3NativeArray.Dispose();
            node4NativeArray.Dispose();
            node5NativeArray.Dispose();
            node6NativeArray.Dispose();
            node7NativeArray.Dispose();
            node8NativeArray.Dispose();
            jobHandleArray.Dispose();
            #endregion
        }
        else
        {
            NativeQueue <SpriteSheetAnimationComponent> sheet0NativeQueue = new NativeQueue <SpriteSheetAnimationComponent>(Allocator.TempJob);
            CopySpriteJob copyTileJob = new CopySpriteJob {
                sheet0NativeQueue = sheet0NativeQueue.AsParallelWriter()
            };
            JobHandle jobHandle = copyTileJob.Schedule(this);
            jobHandle.Complete();

            NativeArray <SpriteSheetAnimationComponent> sheet0NativeArray = new NativeArray <SpriteSheetAnimationComponent>(sheet0NativeQueue.Count, Allocator.TempJob);

            NativeQueueToArrayJob sheet0NativeQueueToArrayJob = new NativeQueueToArrayJob {
                nativeQueue = sheet0NativeQueue,
                nativeArray = sheet0NativeArray,
            };
            jobHandle = sheet0NativeQueueToArrayJob.Schedule();
            jobHandle.Complete();

            sheet0NativeQueue.Dispose();

            if (sortSprite)
            {
                SortLayerJob sortLayerJob = new SortLayerJob {
                    sortArray = sheet0NativeArray
                };
                jobHandle = sortLayerJob.Schedule();
                jobHandle.Complete();
            }

            int visibleTileTotal = sheet0NativeArray.Length;

            NativeArray <Matrix4x4> matrixArray            = new NativeArray <Matrix4x4>(visibleTileTotal, Allocator.TempJob);
            NativeArray <Vector4>   uvArray                = new NativeArray <Vector4>(visibleTileTotal, Allocator.TempJob);
            NativeArray <int>       matIdArray             = new NativeArray <int>(visibleTileTotal, Allocator.TempJob);
            FillArrayForParalleJob  fillArrayForParalleJob = new FillArrayForParalleJob {
                matrixArray   = matrixArray,
                uvArray       = uvArray,
                matIdArray    = matIdArray,
                nativeArray   = sheet0NativeArray,
                startingIndex = 0
            };
            jobHandle = fillArrayForParalleJob.Schedule(sheet0NativeArray.Length, 10);
            jobHandle.Complete();


            int sliceCount = matrixInstanceArray.Length;
            int off        = 0;
            while (off < visibleTileTotal)
            {
                int sheetId   = matIdArray[off];
                int sliceSize = 0;
                while (off + sliceSize < visibleTileTotal && sliceSize < sliceCount)
                {
                    if (matIdArray[off + sliceSize] != sheetId)
                    {
                        break;
                    }
                    sliceSize++;
                }
                NativeArray <Matrix4x4> .Copy(matrixArray, off, matrixInstanceArray, 0, sliceSize);

                NativeArray <Vector4> .Copy(uvArray, off, uvInstanceArray, 0, sliceSize);

                materialPropertyBlock.SetVectorArray(sharedPropertyId, uvInstanceArray);

                Graphics.DrawMeshInstanced(
                    Testing.Instance.mesh,
                    0,
                    GetMaterial(sheetId),
                    matrixInstanceArray,
                    sliceSize,
                    materialPropertyBlock
                    );

                off += sliceSize;
            }

            matrixArray.Dispose();
            uvArray.Dispose();
            matIdArray.Dispose();

            sheet0NativeArray.Dispose();
        }
    }