|
前面两篇文章算是必备的基础知识,从这一节开始就正式进入到代码的编写环节了!在写代码之前,我们来梳理一下地形生成总的思路:
①在第二篇文章中说过了,我们将采用动态生成Mesh来代替常用的Prefab实例化去生成地形。一共有三种基本单位:(1)Face;(2)Block;(3)Chunk。前面两种都已经说过了,而Chunk之所以出现,也是为了渲染的效率考虑,我们把很多个连在一起的Block组成的整体叫作Chunk,这样在渲染时就可以直接渲染Chunk而不是一个一个Block的渲染(计算机在做这种一次做很多事的工作时往往会比一件一件事地做要快)。三种之间的具体关系可以概述为:几个Face构成一个Block,很多Block又构成了Chunk。
②我们来详细说说Chunk类,我们的地形是以Chunk为基本单位的,我们的项目中就采用16x16x100的Chunk(把它当做一个16x16x100的正方体,里面每个小正方体都是Block),我们从第一篇文章可以知道每个Block需要包含一个Vector3的位置信息以及BlockType的方块类型。
由此可以得到以下代码:
①Block的类型
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 每一个Block的类型,Block即Minecraft中的一个方块
/// </summary>
public enum BlockType
{
Nothing,
Air,
Grass_Dirt,
Dirt,
Stone,
Water,
Sand
}②Chunk的数据定义
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// Chunk是很多个Block组成的。
/// 防止一个一个Block的渲染,减少性能消耗。
/// </summary>
public class ChunkData
{
public BlockType[] blocks;//用来保存Chunk中的每一个Block
public int chunkSize = 16;
public int chunkHeight = 100;
public Vector3Int worldPosition;//每一个Chunk都有一个位置
public ChunkData(int chunkSize, int chunkHeight, World world, Vector3Int worldPosition)
{
this.chunkHeight = chunkHeight;
this.chunkSize = chunkSize;
this.worldPosition = worldPosition;
blocks = new BlockType[chunkSize * chunkHeight * chunkSize];
}
}你可能会好奇,为什么没有给Block创建一个类来保存数据,却只有一个BlockType类,那位置信息呢?能发现这个问题说明你是善于思考的,我们之所以没有给它位置信息,是因为我们生成Block是通过动态Mesh的方法,其位置完全可以在运行时通过在Chunk内去循环Block确定位置即可,现在写了只会浪费空间。但是对于Chunk我们就得给它提供一个位置信息去定位这个Chunk. |
|