繁体   English   中英

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

[英]Unity stops responding based mesh vertex-count

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

我知道我意识到改变了我的地形上的 meshChunkSize(给 Vector3[] allVertices 方式较低的元素)修复了过程中无限的“无响应”。 因此,对于大约 2100 个顶点,它总是在 floodfillSampleRate 上以任意数量运行。 当我到达大约 15-20k 个顶点时,它仍然有效,但 unity 停止响应几秒钟,然后返回响应并输出结果。 如果我达到我的默认块大小,即 59k 顶点,即使在 floodFillSampleRate 的值也很低,那么它只是处于“无响应”模式,在我看来是无限的(我已经等了大约 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;

难道你是在“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]); 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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