5-3 将地图单元分配到不同的地图块中

  在上一章中,我们创建了地图块的Prefab,并完成了其相关的脚本。在最后一流了一个问题,就是HexGridChunk.Start方法中的hexMesh.Triangulate(cells);语句会报空引用的错误,这是因为地图块只创建了存放地图单元实例的数组,而这个数组是空的。创建地图单元实例的语句是在HexGrid中,我们需要做的就是将创建的地图单元实例添加到其对应的地图块数组中,而不是在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
private void CreateCell(int x, int z, int i)
{


HexCell cell;
cells[i] = Instantiate<HexCell>(cellPrefab);
cell = cells[i];
//这里不再对cell实例设置父级,将其分配到对应chunk后,由chunk进行实例父级的设置
//cell.transform.SetParent(transform, false);



Text label = Instantiate<Text>(cellLabelPrefab);
//这里不再设置label的父级,而是将其分配到对应chunk中,由chunk进行父级的设置
//label.rectTransform.SetParent(gridCanvas.transform, false);



AddCellToChunk(x, z, cell);
}

/// <summary>
/// 通过cell在数组中的坐标计算后,将其分配到对应的chunk中
/// </summary>
/// <param name="x">cell在整体数组中的横坐标</param>
/// <param name="z">cell在整体数组中的纵坐标</param>
/// <param name="cell">cell自身的实例</param>
private void AddCellToChunk(int x, int z, HexCell cell)
{
}

  我们可以通过地图单元在HexGrid.cells数组中的横纵坐标,计算出当前地图单元应该属于哪个地图块。代码如下:

HexGrid.cs
1
2
3
4
5
6
7
8
9
private void AddCellToChunk(int x, int z, HexCell cell)
{
//通过cell整体数组的横纵坐标,计算出cell属于哪个chunk
int chunkX = x / HexMetrics.chunkSizeX;
int chunkZ = z / HexMetrics.chunkSizeZ;

//通过计算得到的坐标,获取对应chunk的实例
HexGridChunk chunk = chunks[chunkX + chunkZ * chunkCountX];
}

  通过计算结果,我们还可以知道当前地图单元在其对应地图块数组中的下标。有了这个下标,我们就可以将当前地图单元实例分配到对应的地图块数组中了。代码如下:

HexGrid.cs
1
2
3
4
5
6
7
8
9
10
11
private void AddCellToChunk(int x, int z, HexCell cell)
{


//通过cell整体数组坐标,计算出其在对应chunk数组中的下标
int localX = x - chunkX * HexMetrics.chunkSizeX;
int localZ = z - chunkZ * HexMetrics.chunkSizeZ;

//得到下标后,将cell实例添加到对应chunk的数组中
chunk.AddCell(localX + localZ * HexMetrics.chunkSizeX, cell);
}

  接着,我们回到HexGridChunk中,创建AddCell方法。这个方法负责将地图单元实例添加到自身数组中,并且设置地图单元及其UI的父节点。代码如下:

HexGridChunk.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/// <summary>
/// 将cell实例添加到自身的数组中
/// </summary>
/// <param name="index">cell在自身数组的下标</param>
/// <param name="cell">cell的实例</param>
public void AddCell(int index, HexCell cell)
{
//通过下标将cell实例添加到数组中
cells[index] = cell;

//设置cell和cell UI的父节点
cell.transform.SetParent(transform, false);
cell.uiRect.SetParent(gridCanvas.transform, false);
}

  至此我们就完成了将地图单元实例分配到期对应地图块中的功能了。不过现在的代码还是有一些需要清理的地方,例如在HexGrid中依然有进行三角构建的的相关方法。在下一章中,我们要清理这些遗留的代码,让整个地图系统正常运行。

Github代码