Я создаю игру в стиле майнкрафт, которая загружается процедурно. Мир построен из столбцов блоков, которые представляют собой стеки по 16 блоков. Каждый кусок представляет собой куб, сделанный из блоков размером 16x16x16, которые, в свою очередь, состоят из четырехугольников (по соображениям производительности).
Когда мой игрок перемещается, я хочу, чтобы столбцы фрагментов в пределах определенного радиуса отображались. Каждый тик я проверяю, какие столбцы блоков находятся в радиусе от игрока, а затем визуализирую их. Когда это происходит, мир замирает на 1-2 секунды. Я изменил это так, чтобы каждый тик отображал только один фрагмент вместо целого столбца фрагмента. Игра зависает примерно на 0,5 - 1 секунду каждый раз.
Код, выполняющий рендеринг, находится здесь:
// Update is called once per frame
void Update()
{
StartCoroutine("Render");
}
IEnumerator Render()
{
int radius = 2;
Vector3 currentPosition = Camera.main.transform.position;
Vector2 currentChunkPosition = new Vector2((float) Math.Floor(currentPosition.x / Chunk.size), (float) Math.Floor(currentPosition.z / Chunk.size));
float chunkColumnDistance;
for (int x = 0; x < world.Size.x; x++)
{
for (int y = 0; y < world.Size.y; y++)
{
chunkColumnDistance = Mathf.Sqrt((float) Math.Pow(x - currentChunkPosition.x, 2) + (float)Math.Pow(y - currentChunkPosition.y, 2));
if (chunkColumnDistance <= radius)
{
for (int i = ChunkColumn.chunksPerColumn - 1; i > -1; --i)
{
if (world.chunkColumns[x, y].chunks[i].rendered)
{
continue;
}
world.chunkColumns[x, y].chunks[i].Render();
yield return null;
}
}
}
}
}
Я всегда ожидал бы небольшой задержки с каждым обновлением, но не до такой степени, чтобы это было заметно для игрока. В настоящее время я запускаю обновление рендеринга как сопрограмму, но я не уверен, где отсюда перейти к go. Может ли кто-нибудь предложить улучшения.
Для справки, проект находится здесь: https://github.com/JoshPJackson/BlockGame/blob/master/Assets/Scripts/Game.cs
EDIT:
I внес изменения, так что я визуализирую только фрагменты, которые находятся в определенном радиусе от игрока, а не каждый фрагмент в столбце фрагментов, который находится в пределах радиуса проигрывателя. Производительность лучше, но все еще не совсем так.
Обновленный код:
IEnumerator Render()
{
int radius = 2;
Vector3 currentPosition = Camera.main.transform.position;
float chunkDistance;
for (int x = 0; x < world.Size.x; x++)
{
for (int y = 0; y < world.Size.y; y++)
{
for (int i = ChunkColumn.chunksPerColumn - 1; i > -1; --i)
{
chunkDistance = Vector3.Distance(currentPosition, world.chunkColumns[x, y].chunks[i].globalPosition);
if (chunkDistance <= radius * Chunk.size)
{
if (world.chunkColumns[x, y].chunks[i].rendered)
{
continue;
}
world.chunkColumns[x, y].chunks[i].Render();
yield return null;
}
}
}
}
}