简体   繁体   中英

Unity stops responding based mesh vertex-count

I am running ' GenerateFloodFillData ' a number of times in another script. It loops the function in a for-loop based on an int variable X . If i only run the function once ( floodFillSampleRate = 1) then it seems to respond every time. If i up floodFillSampleRate = 10 then Unity editor stops responding 25% out of a few tries. When floodFillSampleRate = 100 then it computes for a while and then stops responding and the process never 'goes back' to responding state. I know why the function takes very long time to compute and that it is also using a while-loop (which is not always recomended). But this should not be an infinity-loop/recursion issue because the function has been executed before.

I know realised that changed the meshChunkSize on my terrain (giving Vector3[] allVertices way lower elements) fixes the infinite 'not responding' on the process. So with around 2100 vertices it always runs through with any number on floodfillSampleRate. When i go up to around 15-20k vertices then it still works but unity stops responding for a few seconds, it then goes back to responding and outputs the result. If i go up to my default chunksize which is 59k vertices at even low values on floodFillSampleRate then it just is in 'not responding' mode for what looks to me infinite (I've waited around 25-30 minutes for the process to return but i didnt).

Is this some time-complexity issue that just makes it so that the more vertices that loops a few times the time it takes is just too long or something? I dont know the time-complexity exactly, but i would assume it atleast is linear, since adding more vertices means just more vertices to queue and loop in the while loop. I doesnt seem that i have an infinite-loop in the code either. I tried framing the whole function with a try-catch (im not sure if im doing this right) and i dont get any error, it just freezes so how can i get an error if unity process is not responding.

private static Queue<Vector3> q = new Queue<Vector3>();
private static List<Vector3> l = new List<Vector3>();

private static void CheckIfQueueNeighbor(int index, float limit, Vector3[] allVertices, Vector3 currentNode)
{
    if (allVertices[index].y - currentNode.y <= limit)
    {
        if (l.Contains(allVertices[index]) == false)
        {
            l.Add(allVertices[index]);
            q.Enqueue(allVertices[index]);
        }
        else
        {
            // Do nothing if already in list
        }
    }
}

public static float GenerateFloodFillData(float heightThresholdValue, MeshFilter meshFilter)
{
    Vector3[] verts = meshFilter.sharedMesh.vertices;
    Vector3 cNode;

    //Initialize
    int width = (int)meshFilter.sharedMesh.bounds.size.x;
    q = new Queue<Vector3>();
    l = new List<Vector3>();

    //Start at index 0, maybe be any corner or vertex in mesh. Investigate more.
    q.Enqueue(verts[0]);

    while (q.Count > 0)
    {
        cNode = q.Dequeue();

        //Add traversable nodes: Left, right, top & bottom
        if ((Array.IndexOf(verts, cNode) - 1) >= 0)
        {
            CheckIfQueueNeighbor(Array.IndexOf(verts, cNode) - 1, heightThresholdValue, verts, cNode);
        }
        if ((Array.IndexOf(verts, cNode) + 1) < verts.Length)
        {
            CheckIfQueueNeighbor(Array.IndexOf(verts, cNode) + 1, heightThresholdValue, verts, cNode);
        }
        if ((Array.IndexOf(verts, cNode) - width) >= 0)
        {
            CheckIfQueueNeighbor(Array.IndexOf(verts, cNode) - width, heightThresholdValue, verts, cNode);
        }
        if (Array.IndexOf(verts, cNode) + width < verts.Length)
        {
            CheckIfQueueNeighbor(Array.IndexOf(verts, cNode) + width, heightThresholdValue, verts, cNode);
        }
    }

    float averageTraversal = (float)l.Count / (float)verts.Length;
    return averageTraversal;
}

This function is run when GUILayout.Button is pressed:

        float floodFillAverageTraversal = 0f;
        for (int i = 0; i < mapPreview.floodFillSampleRate; i++)
        {
            floodFillAverageTraversal += FloodFill.GenerateFloodFillData(mapPreview.floodFillHeightThresholdValue, mapPreview.previewMeshFilter);

            mapPreview.maps[mapPreview.mapIndexSelector].heightMapSettings.noiseSettings.seed = Random.Range(0, int.MaxValue);
            mapPreview.DrawMapInEditor();
        }

        floodFillAverageTraversal /= mapPreview.floodFillSampleRate;

Could it be that you are adding to "q" in "CheckIfQueueNeighbor" function so continuously Dequeuing and Queuing forever??

while (q.Count > 0)
    {
        cNode = q.Dequeue();

And

private static void CheckIfQueueNeighbor(int index, float limit, Vector3[] allVertices, Vector3 currentNode)
{
    if (allVertices[index].y - currentNode.y <= limit)
    {
        if (l.Contains(allVertices[index]) == false)
        {
            l.Add(allVertices[index]);
            q.Enqueue(allVertices[index]); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM