仿我的世界地形

准备工作

alt

创建Cube,添加Icon,场景中新建MapGenerator空物体,挂载MapGenerator脚本,建立白、绿、蓝三个材质球。

    public int mapHeight;
    public int mapWidth;
    public float lacunarity = 0.001f;
    public GameObject tilePrefab;
    public Material[] materials;

alt

为MapGenerator提供生成按钮,通过编辑器拓展方式实现(用Odin更方便)。

[CustomEditor(typeof(MapGenerator))]
public class MapGenerator_Editor : Editor
{
    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();
        if (GUILayout.Button("生成"))
        {
            ((MapGenerator)target).GenerateMap();
        }
    }
}

生成地图

   public void GenerateMap()
    {
        //清理地图
        for (int i = transform.childCount ; i > 0; i--)
        {
            DestroyImmediate(transform.GetChild(i - 1).gameObject);//支持Editor
        }
        //生成地图
        for (int x = 0; x < mapWidth; x++)
        {
            for (int z = 0; z < mapHeight; z++)
            {   
                float y = Mathf.PerlinNoise(x * lacunarity, z * lacunarity) * tileHeightMultiply;
                if (!isSmooth)
                {
                    y = Mathf.Round(y);
                }
                Vector3 pos = new Vector3(x, y, z);
                GameObject go = Instantiate(tilePrefab,transform);
                go.transform.position = pos;
                go.name = y.ToString();
                if (y > 0.7f * tileHeightMultiply)
                {
                    go.GetComponent<MeshRenderer>().material = materials[0];
                }
                else if(y > 0.3f * tileHeightMultiply)
                {
                    go.GetComponent<MeshRenderer>().material = materials[1];
                }
                else 
                {
                    go.GetComponent<MeshRenderer>().material = materials[2];
                }
            }
        }
    }

首先倒序清理地图(正序删除数组长度在变化,会产生错误),生成地图时,y轴高度使用柏林噪声算法平滑生成随机数,并为不同高度的Cube赋予不同颜色的材质做区分。

alt