Как улучшить производительность процедурной генерации мира

Я создаю игру в стиле майнкрафт, которая загружается процедурно. Мир построен из столбцов блоков, которые представляют собой стеки по 16 блоков. Каждый кусок представляет собой куб, сделанный из блоков размером 16x16x16, которые, в свою очередь, состоят из квадратов (по соображениям производительности).

Когда мой игрок перемещается, я хочу, чтобы столбцы фрагментов в пределах определенного радиуса отображались. Каждый тик я проверяю, какие столбцы блоков находятся в радиусе от игрока, а затем визуализирую их. Когда это происходит, мир замирает на 1-2 секунды. Я изменил это так, чтобы каждый тик отображал только один фрагмент вместо целого столбца фрагмента. Игра зависает примерно на 0,5 — 1 секунду каждый раз.

Код, выполняющий рендеринг, находится здесь:

 //Обновление вызывается один раз за кадрvoid Update () {StartCoroutine ("Render");  } IEnumerator Render () {int radius = 2;  Vector3 currentPosition = Camera.main.transform.position;  Vector2 currentChunkPosition = новый Vector2 ((float) Math.Floor (currentPosition.x/Chunk.size), (float) Math.Floor (currentPosition.z/Chunk.size));  float chunkColumnDistance;  for (int x = 0; x  -1; --i) {if (world.chunkColumns [x, y] .chunks [i] .rendered) {продолжить;  } world.chunkColumns [x, y] .chunks [i] .Render ();  yield return null;  }}}}}  

Я всегда ожидал бы небольшой задержки с каждым обновлением, но не до такой степени, чтобы это было заметно для игрока. В настоящее время я запускаю обновление рендеринга в качестве сопрограммы, но я не уверен, что делать дальше. Может ли кто-нибудь предложить улучшения.

Для справки, проект находится здесь: https://github.com/JoshPJackson/BlockGame/blob/master/Assets/Scripts/Game.cs

Я внес изменения, так что я визуализирую только фрагменты, которые находятся в определенном радиусе от проигрывателя, а не каждые кусок в столбце фрагментов, которые находятся в радиусе действия игрока. Производительность лучше, но все еще не совсем так.

Обновленный код:

  IEnumerator Render () {int radius = 2;  Vector3 currentPosition = Camera.main.transform.position;  float chunkDistance;  for (int x = 0; x  -  1; --i) {chunkDistance = Vector3.Distance (currentPosition, world.chunkColumns [x, y] .chunks [i] .globalPosition);  if (chunkDistance  

Копаемся в коде вашего проекта, и похоже, что вы строите весь видимый мир при каждом обновлении. То есть вы создаете новые GameObject для всех видимых квадратов блоков в каждом кадре , а затем выбрасываете их все (надеюсь, иначе у вас будет огромная утечка памяти), прежде чем начинать заново следующий frame.

Более эффективным подходом было бы создать экземпляры всех ваших GameObject один раз, после того как вы определите свой world.chunksColumns.chunks и затем используете SetActive (true) или setActive (false) в вызове рендеринга классов блоков. Тогда приведенный выше код должен работать намного быстрее.

Оцените статью
Gamicon.ru
Добавить комментарий