Unity C#生成Voxel Terrain的自定义网格未正确加载
因此,我正在创建类似于Minecraft的无限地形系统。我自己是出于个人兴趣来学习的。我最有用的所有东西,而且我做出了一些功能来生成立方体的面孔,然后将它们全部添加到一个块中,但是由于某种原因,我得到了一个非常奇怪的东西,其中每一行都是随机随机的比其他人高得多,破坏了整个网格。任何能够理解原因的人,因为我完全失去了这个问题。
注意:突出显示的部分应该是一个奇异的块,它延伸到整个块。它们的每组都落后于上一组,它应该是顶部完全平坦的脸。
// Face Generator
public enum Face { top, bottom, north, south, west, east };
public Mesh GetMeshDataFromFace(Face face, Vector3 pos)
{
Mesh _face = new Mesh();
Vector3[] _normals = new Vector3[4];
if (face == Face.top)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 1, 0),
pos + new Vector3(1, 1, 0),
pos + new Vector3(1, 1, 1),
pos + new Vector3(0, 1, 1)
};
_face.triangles = new int[]{
0, 3, 2, 2, 1, 0
};
_normals = new Vector3[]{
Vector3.up, Vector3.up, Vector3.up, Vector3.up
};
}
if (face == Face.bottom)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 0),
pos + new Vector3(1, 0, 0),
pos + new Vector3(1, 0, 1),
pos + new Vector3(0, 0, 1)
};
_normals = new Vector3[]{
Vector3.down, Vector3.down, Vector3.down, Vector3.down
};
_face.triangles = new int[]{
0, 1, 2, 2, 3, 0
};
}
if (face == Face.north)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 1),
pos + new Vector3(1, 0, 1),
pos + new Vector3(1, 1, 1),
pos + new Vector3(0, 1, 1)
};
_normals = new Vector3[]{
Vector3.right, Vector3.right, Vector3.right, Vector3.right
};
_face.triangles = new int[]{
0, 1, 2, 2, 3, 0
};
}
if (face == Face.south)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 0),
pos + new Vector3(1, 0, 0),
pos + new Vector3(1, 1, 0),
pos + new Vector3(0, 1, 0)
};
_normals = new Vector3[]{
Vector3.left, Vector3.left, Vector3.left, Vector3.left
};
_face.triangles = new int[]{
0, 3, 1, 3, 2, 1
};
}
if (face == Face.west)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 0), // 0
pos + new Vector3(0, 1, 0), // 3
pos + new Vector3(0, 1, 1), // 7
pos + new Vector3(0, 0, 1) // 4
};
_normals = new Vector3[]{
Vector3.back, Vector3.back, Vector3.back, Vector3.back
};
_face.triangles = new int[]{
2, 1, 0, 0, 3, 2
};
}
if (face == Face.east)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(1, 0, 0),
pos + new Vector3(1, 1, 0),
pos + new Vector3(1, 1, 1),
pos + new Vector3(1, 0, 1)
};
_normals = new Vector3[]{
Vector3.forward, Vector3.forward, Vector3.forward, Vector3.forward
};
_face.triangles = new int[]{
0, 1, 2, 2, 3, 0
};
}
_face.SetNormals(_normals);
return _face;
}
块存储数据作为单数字节[] 4096索引的阵列。 这是生成网格的代码。
public Mesh CreateChunkMesh(ChunkObject chunkObj)
{
Chunk chunkData = chunkObj.chunkData;
Mesh mesh = new Mesh();
List<Mesh> meshesToCombine = new List<Mesh>();
for (int i = 0; i < chunkData.blocks.Length; i++)
{
if (chunkData.blocks[i] != 0)
{
Vector3 blockPos = new Vector3((i % 16), Mathf.Floor(i % 256), Mathf.Floor((i % 256) / 16));
Debug.Log(i + " | " + blockPos);
if (i + 256 >= chunkData.blocks.Length)
{
//This is the top layer of blocks.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, 1, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.top, blockPos));
}
}
if (i < 256)
{
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, -1, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.bottom, blockPos));
}
}
if ((i % 256) < 16)
{
//This is the EAST layer of the chunk.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, 0, 1)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.east, blockPos));
}
}
if ((i % 256) >= 240)
{
//This is the WEST layer of the chunk.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, 0, -1)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.west, blockPos));
}
}
if (i % 16 == 0)
{
//This is the NORTH layer of the chunk
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(1, 0, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.north, blockPos));
}
}
if (i % 16 == 1)
{
//This is the SOUTH layer of the chunk.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(-1, 0, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.south, blockPos));
}
}
//This block is not within any of the faces.
//Check each direction of the block
if (i + 256 <= chunkData.blocks.Length)
{
if (chunkData.blocks[i + 255] == 0) //TOP direction
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.top, blockPos));
}
}
if (i - 256 >= 0)
{
if (chunkData.blocks[i - 256] == 0) //BOTTOM Direction
{
//If the block BELOW this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.bottom, blockPos));
}
}
if (i + 1 <= chunkData.blocks.Length - 1)
{
if (chunkData.blocks[i + 1] == 0) //NORTH Direction
{
//If the block NORTH of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.north, blockPos));
}
}
if (i - 1 >= 0)
{
if (chunkData.blocks[i - 1] == 0) //SOUTH Direction
{
//If the block SOUTH of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.south, blockPos));
}
}
if (i + 16 <= chunkData.blocks.Length)
{
if (chunkData.blocks[i + 15] == 0) //WEST Direction
{
//If the block WEST of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.west, blockPos));
}
}
if (i - 16 >= 0)
{
if (chunkData.blocks[i - 16] == 0) //EAST Direction
{
//If the block EAST of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.east, blockPos));
}
}
}
}
CombineInstance[] combine = new CombineInstance[meshesToCombine.Count];
for (int i = 0; i < combine.Length; i++)
{
combine[i].mesh = meshesToCombine[i];
combine[i].transform = chunkObj.transform.localToWorldMatrix;
}
mesh.CombineMeshes(combine);
return mesh;
}
如果有任何必要的详细信息,我不包括让我知道并添加它们,
So, I am in the process of creating a infinite terrain system similar to Minecraft's. I am making it myself out of personal interest to learn. I have most everything working, and I have made some functions to generate the faces of cubes and then I'm adding it all together into a chunk, but for some reason I am getting a really weird thing where each row of the blocks are randomly much higher than the others, ruining the mesh entire. Anyone able to understand why, because I am completely lost as to the issue.
Note: The highlighted part is supposed to be a singular chunk, and it extends upwards over the entire chunk. Each set of them are a slight bit behind the previous, its supposed to be a completely flat face on the top.
// Face Generator
public enum Face { top, bottom, north, south, west, east };
public Mesh GetMeshDataFromFace(Face face, Vector3 pos)
{
Mesh _face = new Mesh();
Vector3[] _normals = new Vector3[4];
if (face == Face.top)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 1, 0),
pos + new Vector3(1, 1, 0),
pos + new Vector3(1, 1, 1),
pos + new Vector3(0, 1, 1)
};
_face.triangles = new int[]{
0, 3, 2, 2, 1, 0
};
_normals = new Vector3[]{
Vector3.up, Vector3.up, Vector3.up, Vector3.up
};
}
if (face == Face.bottom)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 0),
pos + new Vector3(1, 0, 0),
pos + new Vector3(1, 0, 1),
pos + new Vector3(0, 0, 1)
};
_normals = new Vector3[]{
Vector3.down, Vector3.down, Vector3.down, Vector3.down
};
_face.triangles = new int[]{
0, 1, 2, 2, 3, 0
};
}
if (face == Face.north)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 1),
pos + new Vector3(1, 0, 1),
pos + new Vector3(1, 1, 1),
pos + new Vector3(0, 1, 1)
};
_normals = new Vector3[]{
Vector3.right, Vector3.right, Vector3.right, Vector3.right
};
_face.triangles = new int[]{
0, 1, 2, 2, 3, 0
};
}
if (face == Face.south)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 0),
pos + new Vector3(1, 0, 0),
pos + new Vector3(1, 1, 0),
pos + new Vector3(0, 1, 0)
};
_normals = new Vector3[]{
Vector3.left, Vector3.left, Vector3.left, Vector3.left
};
_face.triangles = new int[]{
0, 3, 1, 3, 2, 1
};
}
if (face == Face.west)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(0, 0, 0), // 0
pos + new Vector3(0, 1, 0), // 3
pos + new Vector3(0, 1, 1), // 7
pos + new Vector3(0, 0, 1) // 4
};
_normals = new Vector3[]{
Vector3.back, Vector3.back, Vector3.back, Vector3.back
};
_face.triangles = new int[]{
2, 1, 0, 0, 3, 2
};
}
if (face == Face.east)
{
//Create the mesh for a upwards facing surface.
_face.vertices = new Vector3[] {
pos + new Vector3(1, 0, 0),
pos + new Vector3(1, 1, 0),
pos + new Vector3(1, 1, 1),
pos + new Vector3(1, 0, 1)
};
_normals = new Vector3[]{
Vector3.forward, Vector3.forward, Vector3.forward, Vector3.forward
};
_face.triangles = new int[]{
0, 1, 2, 2, 3, 0
};
}
_face.SetNormals(_normals);
return _face;
}
Chunks store block data as a singular byte[] array of 4096 indexs.
Here is the code for generating the mesh
public Mesh CreateChunkMesh(ChunkObject chunkObj)
{
Chunk chunkData = chunkObj.chunkData;
Mesh mesh = new Mesh();
List<Mesh> meshesToCombine = new List<Mesh>();
for (int i = 0; i < chunkData.blocks.Length; i++)
{
if (chunkData.blocks[i] != 0)
{
Vector3 blockPos = new Vector3((i % 16), Mathf.Floor(i % 256), Mathf.Floor((i % 256) / 16));
Debug.Log(i + " | " + blockPos);
if (i + 256 >= chunkData.blocks.Length)
{
//This is the top layer of blocks.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, 1, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.top, blockPos));
}
}
if (i < 256)
{
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, -1, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.bottom, blockPos));
}
}
if ((i % 256) < 16)
{
//This is the EAST layer of the chunk.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, 0, 1)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.east, blockPos));
}
}
if ((i % 256) >= 240)
{
//This is the WEST layer of the chunk.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(0, 0, -1)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.west, blockPos));
}
}
if (i % 16 == 0)
{
//This is the NORTH layer of the chunk
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(1, 0, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.north, blockPos));
}
}
if (i % 16 == 1)
{
//This is the SOUTH layer of the chunk.
if (!_loadedChunkObjs.ContainsKey(chunkObj.chunkPosition + new Vector3Int(-1, 0, 0)))
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.south, blockPos));
}
}
//This block is not within any of the faces.
//Check each direction of the block
if (i + 256 <= chunkData.blocks.Length)
{
if (chunkData.blocks[i + 255] == 0) //TOP direction
{
//If the block ABOVE this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.top, blockPos));
}
}
if (i - 256 >= 0)
{
if (chunkData.blocks[i - 256] == 0) //BOTTOM Direction
{
//If the block BELOW this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.bottom, blockPos));
}
}
if (i + 1 <= chunkData.blocks.Length - 1)
{
if (chunkData.blocks[i + 1] == 0) //NORTH Direction
{
//If the block NORTH of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.north, blockPos));
}
}
if (i - 1 >= 0)
{
if (chunkData.blocks[i - 1] == 0) //SOUTH Direction
{
//If the block SOUTH of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.south, blockPos));
}
}
if (i + 16 <= chunkData.blocks.Length)
{
if (chunkData.blocks[i + 15] == 0) //WEST Direction
{
//If the block WEST of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.west, blockPos));
}
}
if (i - 16 >= 0)
{
if (chunkData.blocks[i - 16] == 0) //EAST Direction
{
//If the block EAST of this block is air then draw the face.
meshesToCombine.Add(GetMeshDataFromFace(Face.east, blockPos));
}
}
}
}
CombineInstance[] combine = new CombineInstance[meshesToCombine.Count];
for (int i = 0; i < combine.Length; i++)
{
combine[i].mesh = meshesToCombine[i];
combine[i].transform = chunkObj.transform.localToWorldMatrix;
}
mesh.CombineMeshes(combine);
return mesh;
}
If there are any necessary details I didn't include let me know and ill add them.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论