一 、首先创建脚本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
编辑脚本放在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();
}
}
三、将Custom Terrain 脚本挂在地形对象上,结果如下
四、运行场景,然后点击编辑面板上的
设置地形高度按钮
结果如下:
五、经过四之后,如果此时用地形自带的编辑工具刷高地形:
再运行场景,然后点击编辑面板上的
设置地形高度按钮又会回到原来的状态
如何避免这种情况发生呢,在原有的CustomTerrain脚本上进行如下更改:
重新绘制刷高地形:
再运行场景,然后点击编辑面板上的
,结果:
六
六、添加地形重置按钮
点击这个按钮地形回到初建时的平面状态。
总结:上面地形看起来不是很自然,因为randomHeightRange它是0到0.1之间的完全随机值,所以并不能构成看起来就很自然的地形,因此我们需要一种控制随机性的方法,第三篇文章将引入噪音原理,把噪音引用于地形。