5-2 创建地图块Prefab

  在上一章中,我们为了让地图的尺寸更大,加入了“地图块”这个概念,并添加了相关的代码。在这一章中,我们将创建地图块的Prefab,
  我们需要一个新的脚本,用来执行地图块的相关逻辑。代码如下:

HexGridChunk.cs
1
2
3
4
5
6
7
using UnityEngine;
using UnityEngine.UI;

public class HexGridChunk : MonoBehaviour
{

}

  接下来回到Unity的Hierarchy面板中,复制HexGrid对象并重命名为HexGridChunk。删除HexGridChunk挂载的HexGrid.cs脚本,并使用HexGridChunk.cs来代替。然后将其拖入Prefabs文件夹中创建为一个Prefab,再将场景中的HexGridChunk物体删除。

  由于逻辑顺序的改变,在地图初始化的时候,首先要创建地图块。所以我们在HexGrid中添加对HexGridChunk的引用,代码如下:

HexGrid.cs
1
2
3
4
5
6
7
8
public class HexGrid : MonoBehaviour
{
//逻辑变成了 地图初始化 -> 创建chunk ->创建cell
//这里要先引用Chunk的Prefab
public HexGridChunk chunkPrefab;


}

  代码部分完成后,将Prefab文件夹中HexGridChunk拖入到HexGrid组件的chunkPrefab栏中。如下图:

  实例化地图块的逻辑,与实例化地图单元的逻辑相类似。这里我们在HexGrid中创建一个数组,用来保存地图块。代码如下:

HexGrid.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class HexGrid : MonoBehaviour
{
//用来存储实例化的chunk
private HexGridChunk[] chunks;

private void Awake()
{


CreateChunks();
}

/// <summary>
/// 创建地图块,并将创建的实例循环添加至数组chunks中
/// </summary>
private void CreateChunks()
{
//设置数组长宽
chunks = new HexGridChunk[chunkCountX * chunkCountZ];

//双循环,将创建的chunk实例添加到chunks数组中
for (int z = 0, i = 0; z < chunkCountZ; z++)
{
for (int x = 0; x < chunkCountX; x++)
{
HexGridChunk chunk = chunks[i++] = Instantiate(chunkPrefab);
chunk.transform.SetParent(transform);
}
}
}
}

  在HexGridChunk中实例化地图单元的思路,与之前直接在HexGrid中实例化地图单元类似。在Awake方法中设置相关参数,接着在Start方法中进行三角构建。与之前相同,HexGridChunk也需要引用其子物体的canvas和mesh组件实例,同时还需要一个数组来保存所有实例化的地图单元。不过我们在HexGridChunk中只是对数组进行初始化,并不会创建地图单元的实例,创建地图单元实例的步骤仍然在HexGrid中执行。代码如下:

HexGridChunk.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 class HexGridChunk : MonoBehaviour
{
//用来存储属于自己范围内的cell实例
private HexCell[] cells;

//对其子物体中HexMesh 和 Canvas组件实例的引用
//在Unity中,直接将其引用拖入变量对应的栏位即可
[SerializeField] private HexMesh hexMesh;
[SerializeField] private Canvas gridCanvas;

private void Awake()
{
//设置其存储cell数组的长宽
cells = new HexCell[HexMetrics.chunkSizeX * HexMetrics.chunkSizeZ];
}

private void Start()
{
//cell实例会由HexGrid创建
//之后会将实例分配到各个HexGridChunk的数组中,这样再进行mesh的构建
hexMesh.Triangulate(cells);
}
}

  至此我们就完成了HexGridChunk.cs的初步功能。不过当前运行会报空引用的错误,这是因为HexGridChunkhexMesh.Triangulate(cells);这个语句中,参数cells为空。在下一章中,我们将修改HexGrid.cs中的代码,将其创建的地图单元实例分配至各个HexGridChunk的数组中,这样就能解决空引用的错误了。

Github代码