一 、首先创建脚本CustomTerrain  脚本是关于地形数据继承Monobehavior

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System;
using System.Linq;
using UnityEditor;


public class CustomTerrain : MonoBehaviour {
    //这个比例乘以高度图获得地形实际高度
    public Vector2 randomHeightRange = new Vector2(0,0.1f);

    //获取地形(物体)对象
    public Terrain terrain;
    //TerrainData里有地形所有的数据
    public TerrainData terrainData;

    //每次编辑完脚本内容返回编辑器时运行后会执行此方法
    private void OnEnable()
    {
        //初始化地形数据 先获取地形再获取本身的地形数据
        terrain = gameObject.GetComponent<Terrain>();
        terrainData = Terrain.activeTerrain.terrainData;
        Debug.LogError(terrain);
    }
    //由上面得到地形数据的数据结构,我们将在下面方法中对其进行操作
    public void RandomTerrain()
    {
        float[,] heightMap;//创建高度图

        //用地形的高宽设置高度图的尺寸大小
        heightMap = new float[terrainData.heightmapWidth,terrainData.heightmapHeight];
        for (int x=0;x<terrainData.heightmapWidth;x++)
        {
            for (int z= 0; z < terrainData.heightmapHeight;z++)
            {
                heightMap[x, z] = UnityEngine.Random.Range(randomHeightRange.x,randomHeightRange.y);//此处的x和y只是最小与最大值
          
            }
        }
        terrainData.SetHeights(0,0,heightMap);
    }

   

}

 

二、创建编辑面板脚本文件CustomTerrainEditor继承Editor

unity 地形刷平 unity2019地形_unity 地形刷平

编辑脚本放在Editor文件夹下

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
[CustomEditor(typeof(CustomTerrain))]
[CanEditMultipleObjects]
public class CustomTerrainEditor : Editor {

    SerializedProperty randomHeightRange;
    //是否折叠编辑面板
    bool showRandom;
    private void OnEnable()
    {
        //找到需要反复更改的属性 
        randomHeightRange = serializedObject.FindProperty("randomHeightRange");
    }
    //绘制编辑面板
    public override void OnInspectorGUI()
    {
        //更新所有序列化的值
        serializedObject.Update();
        //获取自定义的地形属性脚本组件
        CustomTerrain terrain = (CustomTerrain)target;
        // terrain.randomHeightRange=更改属性值,最好不直接获取值,因为我们
        //要创建的是一个很长的编辑器,带有一堆值,需要花费很长时间调整和设置这些值。
        //而且在此处改完值之后返回到编辑器中所有值会重置,也就是会丢失在检查器中做的所有更改
        //那如何更改呢:我们通过序列化属性   SerializedProperty randomHeightRange;
        #region 
        showRandom = EditorGUILayout.Foldout(showRandom,"Random");
        if (showRandom)
        {
            EditorGUILayout.LabelField("",GUI.skin.horizontalScrollbar);
            GUILayout.Label("Set Height Between Random Values",EditorStyles.boldLabel);
            EditorGUILayout.PropertyField(randomHeightRange);
            if (GUILayout.Button("Random Heights"))
            {
                //传数据绘制地形
                terrain.RandomTerrain();

            }
        }

        #endregion

        //应用发生的所有更改
        serializedObject.ApplyModifiedProperties();

    }
   
}

unity 地形刷平 unity2019地形_数据_02

三、将Custom Terrain 脚本挂在地形对象上,结果如下

unity 地形刷平 unity2019地形_unity 地形刷平_03

四、运行场景,然后点击编辑面板上的

unity 地形刷平 unity2019地形_unity 地形刷平_04

设置地形高度按钮

unity 地形刷平 unity2019地形_System_05

结果如下:

unity 地形刷平 unity2019地形_System_06

unity 地形刷平 unity2019地形_System_07

五、经过四之后,如果此时用地形自带的编辑工具刷高地形:

unity 地形刷平 unity2019地形_unity 地形刷平_08

再运行场景,然后点击编辑面板上的

unity 地形刷平 unity2019地形_unity 地形刷平_04

设置地形高度按钮又会回到原来的状态

unity 地形刷平 unity2019地形_System_06

如何避免这种情况发生呢,在原有的CustomTerrain脚本上进行如下更改:

unity 地形刷平 unity2019地形_数据_11

重新绘制刷高地形:

unity 地形刷平 unity2019地形_重置_12

 

再运行场景,然后点击编辑面板上的

unity 地形刷平 unity2019地形_unity 地形刷平_04

,结果:

unity 地形刷平 unity2019地形_重置_14


六、添加地形重置按钮

unity 地形刷平 unity2019地形_重置_15

unity 地形刷平 unity2019地形_unity 地形刷平_16

unity 地形刷平 unity2019地形_数据_17

点击这个按钮地形回到初建时的平面状态。

总结:上面地形看起来不是很自然,因为randomHeightRange它是0到0.1之间的完全随机值,所以并不能构成看起来就很自然的地形,因此我们需要一种控制随机性的方法,第三篇文章将引入噪音原理,把噪音引用于地形。