1

我正在尝试在我的地图上生成一个网格并根据柏林噪声值添加节点。根据从某个位置的 perlin 噪声获得的值,我将添加一个新节点,该节点将具有某种类型,例如 Mountain、Water 等来表示 terrian。在这里,我试图使其值大于 0.5,这意味着它只有山脉,因此黑色立方体应该围绕山区,但是,我的黑色立方体与柏林噪声中的山区不匹配,我似乎无法弄清楚我为什么会出错。希望能深入了解我如何实现这一目标。

private void LocateWalkableCells()
{
    for(int z = 0; z < Height; z++)
    {
        for(int x = 0; x < Width; x++)
        {
            noise = GetNoiseValue(x, z);
            if(noise > 0.5) {
                grid[x,z] = new Node(new Vector3(x, 0, z), TerrainType.Mountain, 1);
            } 
            else {
                grid[x,z] = new Node(new Vector3(x, 0, z), TerrainType.Grass, 1);
            }
        }
    }
}

private float GetNoiseValue(int x, int z)
{
    int pos = (x * Width) + z;
    return Mathf.Round(terrainGenerator.noiseArray[pos] * 10) / 10;
}

// Draw gizmos to visualize colour
void OnDrawGizmos()
{
    Gizmos.DrawWireCube(transform.position, new Vector3(Width, 1, Height));
    if(grid != null)
    {
        foreach(Node n in grid)
        {
            if(n.TerrainType == TerrainType.Grass)
            {
                Gizmos.color = Color.green;
            } 
            else if(n.TerrainType == TerrainType.Mountain)
            {
                Gizmos.color = Color.black;
            } 

            Gizmos.DrawCube(n.Position, Vector3.one * (nodeDiameter - .1f));
        }
    }
}

noiseArray在以下代码中用于地形的顶点:

vertices = new Vector3[(Width + 1) * (Depth + 1)];
noiseArray = PerlinNoise();

int i = 0;
for(int z = 0; z <= Depth; z++)
{
    for(int x = 0; x <= Width; x++)
    {
        var currentHeight = noiseArray[i];

        if(currentHeight > HeightThreshold)
        {
            currentHeight *= HeightMultiplier;
        }

        vertices[i] = new Vector3(x, currentHeight, z);
        i++;
    }
}

输出 在此处输入图像描述

建议答案的结果

似乎仍然错过了一些山区,用绿色而不是黑色着色。 在此处输入图像描述

4

1 回答 1

2

它认为问题出在

var pos = (x * Width) + z;

因为x您是否在网格宽度上编制索引,您可能更愿意

var pos = z * Width + x;

换句话说,你想要

  • 跳过z
  • 每行都有Width元素
  • 然后从那里取第xth 个元素

假设您的地形是按行排列的。

或者如果它是按列排列的(这很不寻常但可能)

var pos = x * Height + z;

或者换句话说

  • 跳过x
  • 每列都有Height元素
  • 然后从那里取第zth 个元素

另见将一维数组的索引转换为二维数组,即行和列


更新

现在您已经展示了它需要的地形生成代码

var pos = z * (Width + 1) + x;

因为地形数组实际上Width + 1每行都有元素。

于 2022-02-22T19:58:47.307 回答