Unity перестает отвечать на основании меня sh счетчик вершин - PullRequest
0 голосов
/ 19 марта 2020

Я запускаю ' GenerateFloodFillData ' несколько раз в другом скрипте. Он зацикливает функцию в for-l oop на основе переменной int X . Если я запускаю функцию только один раз ( floodFillSampleRate = 1), то она, кажется, отвечает каждый раз. Если я набрал floodFillSampleRate = 10, тогда редактор Unity перестает отвечать на 25% из нескольких попыток. Когда floodFillSampleRate = 100, он некоторое время вычисляется, а затем перестает отвечать, и процесс никогда не «возвращается» в состояние ответа. Я знаю, почему для вычисления функции требуется очень много времени и что она также использует while-l oop (что не всегда рекомендуется). Но это не должно быть проблемой бесконечного цикла / рекурсии, потому что функция была выполнена раньше.

Я знаю, понял, что изменение meshChunkSize на моей местности (давая Vector3 [] allVertices способ более низких элементов) исправляет бесконечность ' не отвечает на процесс. Таким образом, с примерно 2100 вершинами он всегда проходит с любым числом в floodfillSampleRate. Когда я go до примерно 15-20 тысяч вершин, он все еще работает, но единица перестает отвечать на несколько секунд, затем возвращается к ответу и выводит результат. Если я go до моего размера по умолчанию, который составляет 59k вершин при даже низких значениях на floodFillSampleRate, то он просто находится в режиме «не отвечает» на то, что мне кажется бесконечным (я ждал около 25-30 минут, пока процесс вернуться, но я не сделал).

Это какая-то проблема сложности времени, которая просто делает так, что больше вершин, которые повторяются несколько раз, занимает слишком много времени или что-то в этом роде? Я точно не знаю сложность времени, но я бы предположил, что она по крайней мере линейна, поскольку добавление большего количества вершин означает просто большее количество вершин в очередь и l oop в то время как l oop. Мне не кажется, что у меня есть бесконечный-l oop в коде либо. Я попытался создать всю функцию с помощью 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.

        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;

1 Ответ

0 голосов
/ 20 марта 2020

Может ли быть так, что вы добавляете к "q" в функции "CheckIfQueueNeighbor" так непрерывно, очереди и очереди навсегда ??

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]); 
...