Mesh地形生成,切割,保存为文件

效果展示:
在这里插入图片描述
在这里插入图片描述
可直接使用的完整代码在本文最后

工具介绍:

工具

  1. Auto Cutting属性,勾选该属性后,Each Terrain Size属性失效,脚本会根据Terrain Size属性自动划分网格,单个网格大小不会大于256*256.
  2. Height Map属性用来存放灰度图
  3. Terrain Height、Terrain Size 用来指定mesh的高度和大小
  4. 在Auto Cutting属性未勾选的情况下, Each Terrain Size属性可以用来指定每块地图的大小,属性要求必须能被TerrainSize整除
  5. Terrain Mat规定了地形的材质
  6. Origin属性为Mesh的父对象,可为空,默认为脚本所在对象
  7. 勾选Create Prefab属性,会将动态生成的Mesh文件保存为Prefab,在Assets文件夹下
Mesh基础知识:

https://catlikecoding.com/unity/tutorials/procedural-grid/

根据灰度图生成Mesh

在读取图像之前,务必勾选Read/Write Enable属性
在这里插入图片描述
单张Mesh的话,我们需要做的只是对它顶点坐标的Y值做一些手脚

 vertices.Add(new Vector3(i, HeightMap.GetPixel(X,Y).grayscale * TerrainHeight,j));

HeightMap.GetPixel((int)a,(int)b).grayscale;可以对图像灰度值进行采样

对Mesh进行切割

由于Mesh的限制,单张Mesh大小不能大于256*256,而且,我们通常不会把整个地图全部加载出来,地图分块是必须的
所谓切割,其实就是分批对灰度图采样

vertices.Add(new Vector3(TX*EachTerrainSize+i, HeightMap.GetPixel(X,Y).grayscale * TerrainHeight, TY*EachTerrainSize+j));

需要注意,无论TerrainSize值为多少,整张灰度图都会被利用到,就是说,在采样之前有一个缩放的过程

int X =(int)((float)TX * (float)EachTerrainSize *((float)MapWidth/(float)TerrainSize) + (float)i * ((float)MapWidth / (float)TerrainSize));
int Y = (int)((float)TY * (float)EachTerrainSize *((float)MapHeight / (float)TerrainSize) + (float)j * ((float)MapHeight / (float)TerrainSize));
Mesh切割之后有缝隙问题

这是因为,两个相邻的Mesh中间的连线并没有连接起来
在这里插入图片描述
我的做法是,规定255*255为最大单片Mesh大小,剩下的预留,用来补间,排除不需要补间的情况

			List<Vector3> vertices = new List<Vector3>();
            List<int> triangles = new List<int>();
            //只有在单片Mesh(不切割)的情况下,EachTerrainSize才有可能==256
            int EachTerrainSize_1 = EachTerrainSize == 256 ? 256 : EachTerrainSize + 1;
            for (int i = 0; i < EachTerrainSize_1; i++)
            {
   
                for (int j = 0; j < EachTerrainSize_1; j++)
                {
   
                    if (j == EachTerrainSize_1 && TX >= MAXXY-1)
                    {
   
                        break;
                    }
                    if (i == EachTerrainSize_1 && TY >= MAXXY - 1)
                    {
   
                        break;
                    }
                    int X =(int)((float)TX * (float)EachTerrainSize *((float)MapWidth/(float)TerrainSize) + (float)i * ((float)MapWidth / (float)TerrainSize));
                    int Y = (int)((float)TY * (float)EachTerrainSize *((float)MapHeight / (float)TerrainSize) + (float)j * ((float)MapHeight / (float)TerrainSize));
                    vertices.Add(new Vector3(TX*EachTerrainSize+i, HeightMap.GetPixel(X,Y).grayscale * TerrainHeight, TY*EachTerrainSize+j));
                    if (i == 0 || j == 0) continue;
                    triangles.Add(EachTerrainSize_1 * i + j);
                    triangles.Add
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值