4-7 地图单元的垂直方向扰动

  在上一章中,我们取消了地图中所有顶点垂直方向的扰动,这样每个地图单元的六边形部分有变得平整了。但是取消垂直方向的扰动并不是一个好办法,我们应该让垂直方向的扰动作用在整个地图单元上,而不是单一的顶点。这样既保留了每个地图单元平坦的表面,又能让不同的地图单元之间存在差别。
  按照这个思路,比较好的做法是对一个地图单元海拔高度进行扰动,并且使用一个强度系数来控制扰动的缩放比例。在HexMetrics.cs里添加一个强度系数。1.5的值就能使不同的地图单元之间存在一些差别,这大概是一级阶梯的高度。代码如下:

HexMetrics.cs
1
2
3
4
5
6
7
8
9
public int Elevation
{
//海拔高度扰动强度系数
//为了保持cell顶部六边形的平坦,这里不再对cell的每个顶点单独进行垂直方向的扰动
//改为对一个cell整体海拔高度进行扰动,然后再乘以一个强度系数
public const float elevationPerturbStrength = 1.5f;


}

  接下来,我们回到HexCell.Elevationset属性中,在这里设置每个地图单元海拔高度的时候,进行扰动,并乘以强度系数。代码如下:

HexCell.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public int Elevation
{


set
{
elevation = value;
Vector3 position = transform.localPosition;
position.y = value * HexMetrics.elevationStep;

//这里对cell整体的海拔高度进行扰动,并乘以强度系数
position.y += (HexMetrics.SampleNoise(position).y * 2f - 1f) * HexMetrics.elevationPerturbStrength;

transform.localPosition = position;

Vector3 uiPosition = uiRect.localPosition;

//同样,UI也是扰动后的高度
uiPosition.z = -position.y;

uiRect.localPosition = uiPosition;
}
}

  最后,我们需要在地图初始化的时候,就对每个地图单元的海拔高度进行扰动,额否则的话地图在刚被创建的时候,整体都是平坦的。我们在HexGrid.CreateCell方法中,UI创建后初始化每个地图单元的高度。代码如下:
  这里还需要注意一点,在HexGrid.Awake方法中,要先执行HexMetrics.noiseSource = noiseSource;语句,然后再执行地图单元创建的语句。否则在创建地图单元的时候,就会有一个空引用的错误,因为在创建地图单元的时候我们还没有获取彩色噪点图。代码如下:

HexGrid.cs
1
2
3
4
5
6
7
private void CreateCell(int x, int z, int i)
{


//在地图初始状态下,每个cell的海拔高度都经过扰动
cell.Elevation = 0;
}

  至此我们就完成了地图单元高度的扰动。我们发现当一个地图单元高度产生变化的时候,与之相邻的矩形和三角形连接区域,并没有升高到其对应的高度,这个问题我们将在下一章解决。

Github代码