Unity停止响应基于网格的顶点数

问题描述 投票:0回答:1

我在另一个脚本中多次运行'GenerateFloodFillData'。它基于int变量X在for循环中循环执行该函数。如果我只运行一次函数(floodFillSampleRate = 1),那么它似乎每次都会响应。如果我最多floodFillSampleRate = 10,则Unity编辑器会在几次尝试中停止响应25%。当floodFillSampleRate = 100时,它会计算一段时间,然后停止响应,并且该过程永远不会“返回”到响应状态。我知道为什么该函数需要很长的时间进行计算,并且还使用了while循环(并不总是建议这样做)。但这不应该是无限循环/递归问题,因为该函数之前已经执行过。

[我知道,在我的地形上更改了meshChunkSize(将Vector3 [] allVertices赋予下部元素)可以修复过程中的无限“不响应”。因此,在大约2100个顶点上,始终会在FloodfillSampleRate上运行任意数量的顶点。当我上升到大约15-20k个顶点时,它仍然可以工作,但unity停止响应几秒钟,然后返回响应并输出结果。如果我使用默认的块大小,即在FloodFillSampleRate上的低值时为59k顶点,那么对于我来说无限的只是处于“不响应”模式(我已经等待了25-30分钟,该过程才返回,但是我没有)。

这是否是一些时间复杂性的问题,只是为了使更多的顶点循环数次所花费的时间太长或有点?我不确切地知道时间复杂度,但是我认为它至少是线性的,因为增加更多的顶点意味着更多的顶点可以在while循环中排队和循环。我似乎也没有代码中的无限循环。我尝试用try-catch框架整个功能(我不确定我是否正确地做到了这一点),但我没有收到任何错误,它只是冻结了,所以如果统一程序没有响应,我怎么能得到错误。

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;
}

此功能在按下GUILayout.Button时运行:

        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;
c# unity3d while-loop infinite-loop flood-fill
1个回答
0
投票

可能是您要在“ CheckIfQueueNeighbor”函数中添加到“ q”,以便永远持续出队和排队吗?

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

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]); 
© www.soinside.com 2019 - 2024. All rights reserved.