微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Unity Job System抛出范围异常,并告诉我调用jobHandle.complete,即使我有它

如何解决Unity Job System抛出范围异常,并告诉我调用jobHandle.complete,即使我有它

这是我无法真正理解的错误,我不明白为什么索引为-1?并且所有这些即时错误都被-1抵消了。

IndexOutOfRangeException:索引-1超出ReadWriteBuffer中受限制的IJobParallelFor范围[0 ... 799]。 ReadWriteBuffers被限制为只能读取和写入作业索引处的元素。您可以使用双重缓冲策略来避免由于与作业中的相同元素并行读写而导致的竞争情况。

我只是创建了一个行进的基于3d噪声的多维数据集洞穴生成器,该生成器在没有统一的作业系统且运行缓慢的情况下工作,因此我认为id可以尝试这样做以提高速度。

这是我的所有代码: (这可能很糟,但是id在作业系统上做了其他教程,并且想跳入更困难的事情)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Jobs;
using Unity.Collections;
using Unity.Burst;
using Unity.Jobs;
using Unity.Mathematics;
using System;
using System.Linq;

public class WorldMesher : MonoBehavIoUr
{
    bool vertArrayReady = false;

    JobHandle worldMesherJobHandle; // 1
    updateworldMeshJob worldMesherJob;

    [Header("Noise Parameters")]
    public float noiseScale;
    public float noiseAmplitudeScale;
    public float NoiseThreshold3d;
    
    [Header("chunk values")]
    public int widthX;
    public int lengthz;
    public int heighty;

    [Header("References and Prefabs")]
    public MeshFilter worldMeshFilter;
    public MeshCollider worldMeshCollider;
    private Mesh worldMesh;



    NativeArray<Vector4> pointVertices;
    NativeArray<Vector3> meshVertices;
    NativeArray<int> meshTriangles;
    int trisnvertIndex; // set to zero pls

    void Start()
    {
        worldMesh = worldMeshFilter.mesh;
        worldMesh.MarkDynamic();



        pointVertices =
            new NativeArray<Vector4>(widthX * lengthz * heighty,Allocator.Persistent);

        meshVertices =
            new NativeArray<Vector3>(widthX * lengthz * heighty * 16,Allocator.Persistent);

        meshTriangles =
            new NativeArray<int>(widthX * lengthz * heighty * 16,Allocator.Persistent);

        for (int x = 0; x < widthX; x++)
        {
            for (int y = 0; y < heighty; y++)
            {
                for (int z = 0; z < lengthz; z++)
                {
                    for (int i = 0; i < 8; i++)
                    {
                        Vector3 thePoint = new Vector3(x,y,z) + CornerTable2[i];
                        pointVertices[z + x + y] = new Vector4(thePoint.x,thePoint.y,thePoint.z,0);
                    }
                }
            }
        }
        vertArrayReady = true;
    }

    private struct updateworldMeshJob : IJobParallelFor
    {
        public NativeArray<Vector3> vertices;


        public NativeArray<int> triangles;

        //[NativedisableParallelForRestriction]
        public NativeArray<Vector4> terrainMapVerts;


        public float noise;
        public float Amplitude;
        public float Threshold;
        public int trisAndVertsIndex;

        public int maxX;
        public int maxZ;
        public int maxY;
        
        
        int[] getCubeConfig(NativeArray<Vector4> myPoints,int indexOffset)
        {
            int[] eightCubePoints = { 0,0};
            for (int i = 0; i < 8; i++)
            {
                if (myPoints[i+ indexOffset].w > Threshold)
                {
                    eightCubePoints[i] = 1;
                }
                else
                {
                    eightCubePoints[i] = 0; ;
                }
            }
            return eightCubePoints;
        }

        int bytetoInt(int[] myByte)
        {
            int myInt = 0;
            for (int i = 0; i < 8; i++)
            {
                if (myByte[i] == 1)
                {
                    myInt += Convert.ToInt32(Math.Pow(2,i));
                }
            }
            return (myInt);
        }

        float NoiseValues(Vector3 pointPosition)// returns true or false for a given point,whether than point is in or out of the "mesh"
        {
            float x = pointPosition.x;
            float y = pointPosition.y;
            float z = pointPosition.z;
                y += 1;                             //3d perlin noise comes across as symetrical so a offset is needed,in a seeded world gen this wouldnt be necessary.
                z += 2;
                x += 3;
                float xy = Mathf.PerlinNoise(x * noise,y * noise);
                float xz = Mathf.PerlinNoise(x * noise,z * noise);
                float yz = Mathf.PerlinNoise(y * noise,z * noise);
                float yx = Mathf.PerlinNoise(y * noise,x * noise);
                float zx = Mathf.PerlinNoise(z * noise,x * noise);
                float zy = Mathf.PerlinNoise(z * noise,y * noise);
                return (xy + xz + yz + yx + zx + zy) / 6;
        }

        public void Execute(int i)
        {
            Vector3 Pos = new Vector3(terrainMapVerts[i].x,terrainMapVerts[i].y,terrainMapVerts[i].z);
            terrainMapVerts[i] = new Vector4(terrainMapVerts[i].x,terrainMapVerts[i].z,NoiseValues(Pos));

            if ((i+1)%8 == 0 )
            {
                //build the cubes mesh and add data to tris and verts arrays;
                Vector3 cubeStartPoint = new Vector3(terrainMapVerts[i - 8].x,terrainMapVerts[i - 8].y,terrainMapVerts[i - 8].z);
                drawCube(cubeStartPoint,bytetoInt(getCubeConfig(terrainMapVerts,i - 8)));
            }
        }

        void drawCube(Vector3 cubeZeroPosition,int triangleTableIndex)
        {
            int[,] myTriangleTable = new int[,] {

        {-1,-1,-1},{0,8,3,1,9,{1,2,10,{9,{2,{3,11,{4,7,4,{8,{11,5,{5,{10,{7,6,{6,{-1,-1}

    };
            Vector3[,] myEdgeTable = new Vector3[12,2] {

        { new Vector3(0.0f,0.0f,0.0f),new Vector3(1.0f,0.0f) },{ new Vector3(1.0f,1.0f,{ new Vector3(0.0f,new Vector3(0.0f,1.0f),1.0f) },1.0f) }

    };

            if (triangleTableIndex == 0 || triangleTableIndex == 255)
            {
                return;
            }
            else
            {
                for (int i = 0; i < 16; i++)
                {
                    if (myTriangleTable[triangleTableIndex,i] == -1)//if -1 is found then we have added all the points of that mesh.
                    {
                        break;
                    }
                    else
                    {
                        int edgeTableIndex = myTriangleTable[triangleTableIndex,i];
                        Vector3 vertex1 = myEdgeTable[edgeTableIndex,0] + new Vector3(cubeZeroPosition.x,cubeZeroPosition.y,cubeZeroPosition.z);
                        Vector3 vertex2 = myEdgeTable[edgeTableIndex,1] + new Vector3(cubeZeroPosition.x,cubeZeroPosition.z);
                        Vector3 triangLevertexPosition = vertex1 + (vertex2 - vertex1) / 2;

                        vertices[trisAndVertsIndex] = (triangLevertexPosition);
                        triangles[trisAndVertsIndex] = (trisAndVertsIndex - 1);
                    }


                }
            }
        }

    }

    // Update is called once per frame
    void Update()
    {
        if (vertArrayReady)
        {
            worldMesherJob = new updateworldMeshJob()
            {
                vertices = meshVertices,triangles = meshTriangles,terrainMapVerts = pointVertices,noise = noiseScale,Amplitude = noiseAmplitudeScale,Threshold = NoiseThreshold3d,trisAndVertsIndex = 0,maxX = widthX,maxZ = lengthz,maxY = heighty
            };
            JobHandle worldMesherJobHandle =
                worldMesherJob.Schedule(7999,800);
        }
    }


    private void LateUpdate()
    {
        if (Input.GetKeyDown(KeyCode.G))
        {
            worldMesherJobHandle.Complete();

            worldMesh.SetVertices(worldMesherJob.vertices);

            worldMesh.triangles = meshTriangles.ToArray();

            worldMesh.Recalculatenormals();

            worldMeshFilter.mesh = worldMesh;
            worldMeshCollider.sharedMesh = worldMesh;
        }

    }




    private void OnDestroy()
    {
        meshVertices.dispose();
        meshTriangles.dispose();
        pointVertices.dispose();
    }


    Vector3Int[] CornerTable2 = new Vector3Int[8] {

        new Vector3Int(0,0),new Vector3Int(1,new Vector3Int(0,1),1)

    };

}

解决方法

问题出在这里:

if ((i+1)%8 == 0 )
{
    //build the cubes mesh and add data to tris and verts arrays;
    Vector3 cubeStartPoint = new Vector3(terrainMapVerts[i - 8].x,terrainMapVerts[i - 8].y,terrainMapVerts[i - 8].z);
    drawCube(cubeStartPoint,byteToInt(getCubeConfig(terrainMapVerts,i - 8)));
}

注意:terrainMapVerts[i - 8]

i7时会产生异常,原因是:

7 - 8 = -1

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。