如何提高程序世界生成性能

How to improve procedural world generation performance

我正在创建一个程序加载的 minecraft 风格的游戏。世界是由 16 个块堆叠而成的块列构建的。每个块都是一个由 16x16x16 块制成的立方体,这些块又由四边形制成(出于性能原因)。

当我的播放器四处移动时,我希望渲染特定半径内的块列。每个 tick 我检查哪些块列在玩家的半径内,然后渲染它们。发生这种情况时,世界会冻结 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;
               }
           }
        }
    }
}

我总是希望每次更新都有一点延迟,但不会到玩家能注意到的程度。我目前 运行 渲染更新作为协程,但我不确定从这里去哪里。谁能提出改进建议。

作为参考,项目在这里: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 < 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;
                    }
                }
            }
        }
    }

深入研究您的项目代码,您似乎在每次更新时都在构建整个可见世界。也就是说,您正在为所有可见块四边形 每帧 创建新的游戏对象,然后在重新开始之前将它们全部扔掉(希望如此,否则您将发生巨大的内存泄漏)下一帧。

一种更有效的方法是在定义 world.chunksColumns.chunks 之后实例化所有游戏对象一次,然后在块 类 中使用 SetActive(true)setActive(false)'呈现调用。那么上面的代码应该 运行 快得多。