Почему завершение цикла for приводит к тому, что NavMeshAgent начинает двигаться быстрее? - PullRequest
0 голосов
/ 29 апреля 2018

Этот код работал нормально и все, но он, казалось, останавливался, когда деревья начинали проникать в свои тысячи экземпляров. Агент navmesh будет просто ждать в своем текущем положении и ничего не делать, пока не появится новая партия деревьев, а затем просто переместится на одно и снова сделает паузу. Но как только я завершу цикл for, он будет непрерывно перемещаться от дерева к дереву по желанию. Почему это? Я думал, что он обновил фрейм, как только код OnCollision был решен. Это потому, что в списке было слишком много вещей для сортировки?

Код:

    void OnCollisionEnter(Collision collision)
{
    GameObject data = GameObject.Find("Data");
    List<GameObject> treeLists = data.GetComponent<DataStorage>().treeList;
    for (removeArea = 0; treeLists.Count > removeArea; removeArea++)
    {
        if (treeLists[removeArea] != null)
            if (collision.gameObject.name == treeLists[removeArea].name)
             {
                 GameObject.Destroy(collision.gameObject);
                 treeLists[removeArea] = null;
                 removeArea = treeLists.Count; //Added this 
             }
    }
}

removeArea должен был быть для чего-то еще, что я решил отказаться. Он не используется нигде в коде.

Есть ли способ заставить его обработать цикл for перед рендерингом следующего кадра?

1 Ответ

0 голосов
/ 02 мая 2018

Если вам нужно проделать большую работу, которая не может уместиться в одном обновлении, используйте сопрограмму . Но в вашем случае вам может понадобиться только улучшить свой алгоритм.

Поскольку вы предоставили только OnCollisionEnter, я могу помочь только улучшить этот метод, и вы будете нести ответственность за изменение остальной части кода для его проверки.

Сначала измените тип treeList с List на HashSet в DataStorage. Наборы хороши, когда вы хотите быстро вставить, удалить и содержать. Больше информации о комплектах . При этом вам больше не нужно будет перебирать всю коллекцию, чтобы найти, кто столкнулся. Удаление петли также позволяет удалить GameObject прямо из набора. Это необходимо, поскольку у вас не может быть дубликатов в наборе (где вы изначально установили ссылку на gameObject на ноль). Ваш новый OnCollisionEnter сейчас:

void OnCollisionEnter(Collision collision) {
    GameObject data = GameObject.Find("Data");
    var treeList = data.GetComponent<DataStorage>().treeList;

    // compare references
    if (treeList.Contains(collision.gameObject)) {
        treeList.Remove(collision.gameObject);
        GameObject.Destroy(collision.gameObject);
    }
}

Надеюсь, это поможет и направит вас на правильный путь.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...