Chinaunix首页 | 论坛 | 博客
  • 博客访问: 27612
  • 博文数量: 9
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 328
  • 用 户 组: 普通用户
  • 注册时间: 2013-04-22 15:20
个人简介

第三方第三方士大夫奇才

文章分类

全部博文(9)

文章存档

2015年(3)

2014年(2)

2013年(4)

我的朋友

分类: Python/Ruby

2013-05-22 16:00:30

最近有点空闲时间,就打算把以前项目的场景资源转移到Unity3D里面去,首先第一步做的就是地形的移植,在这过程中绕了不少弯路,专门记录下。

场景地形的移植首先想到的办法是通过高度图来进行中转,但由于Unity文档中对导入高度图的格式说明不够详细,试验了很多次都没能正确导入,最后只好作罢,转为直接通过c#脚本载入。

1) 导出。首先第一步是将地形的高度数据导出到文件中,由于这个文件等下读取的代码也是自己做,所以格式自己清楚就可以了,我是将每一个顶点的高度值以一个float依次保存在了一个二进制文件中。

2) U3D读取2进制文件。 现在我们有了存有地形高度信息的文件,接下来要做的事就是通过U3D去读取并解析这个二进制文件,这里我们通过TextAsset来载入。这里需要注意,需要通过TextAsset来载入的二进制文件,要将后缀名改为.bytes再加入到工程中。

3) U3D中地形的高度信息是保存在terrain.terrainData中的,起初认为只需要将读到的数据塞进去就可以了,后来发现也并非如此,主要存在下面几个问题:

  1. HeightmapResolution的大小,也就是导入的顶点数据的多少,需要和你数据的大小对应,并且其大小应为2n +1。
  2. U3D中地形所存储的数据并不是一个绝对的高度数值,而是一个相对的高度值,这个高度的分母应当是当前地形中最高值与最低值之间的差值。也就是这个值决定了这块地形的高度上限。对应的代码中的属性是terrain.terrainData.size.y。
  3. U3D地形中是不存在负值的,如果你导入的地形数据中有负值,那么请将他们通过整体向上提升的方式,在保证相互之间高度的同时提升到0以上。

最后放上截图一张

 

 

具体的实现代码如下:

 
  1. using UnityEngine;  
  2. using System.Collections;  
  3. using System.IO;   
  4.   
  5.   
  6. public class TerrainLoader : MonoBehaviour {  
  7.       
  8.     public string HeightDataFile;  
  9.       
  10.     public int MapSize;  
  11.       
  12.     public Terrain terrain;  
  13.       
  14.     // Use this for initialization  
  15.     void Start () {  
  16.         // 读取资源  
  17.     TextAsset TA =  Resources.Load(HeightDataFile) as TextAsset;  
  18.           
  19.         byte[] buff = TA.bytes;   
  20.             buff[buff.Length-1] = 0;  
  21.           
  22.     float[,] data = new float[MapSize,MapSize];  
  23.           
  24.     int index = 0;  
  25.     float min = 0;  
  26.     float max = 0;  
  27.           
  28.         // 将二进制转换为float  
  29.     for(int i = 0; i
  30.     {  
  31.         for(int j = 0; j
  32.         {  
  33.             data[i,j] = System.BitConverter.ToSingle( buff, index );  
  34.             index += 4;   
  35.             if(min > data[i,j])  
  36.                 min = data[i,j];  
  37.             if(max < data[i, j])  
  38.                 max = data[i,j];          
  39.         }  
  40.     }  
  41.           
  42.         // 计算出地形最大值与最小值的高度差  
  43.     float detailHeight = max - min;  
  44.           
  45.         // 设置地形的最大高度  
  46.     terrain.terrainData.size = new Vector3(512,detailHeight,512);  
  47.           
  48.         // 将地形整体上移,消灭负值  
  49.     for(int i = 0; i
  50.     {  
  51.         for(int j = 0; j
  52.         {  
  53.             if(min < 0)  
  54.             {  
  55.                 data[i,j] = data[i,j] - min;  
  56.             }  
  57.             data[i,j] = data[i,j] / detailHeight;  
  58.         }  
  59.     }  
  60.            
  61.     // 设置分辨率  
  62.     terrain.terrainData.heightmapResolution = MapSize;  
  63.           
  64.             // 导入高度数据  
  65.     terrain.terrainData.SetHeights(0, 0, data);  
  66.       
  67.     }  
  68.       
  69.     // Update is called once per frame  
  70.     void Update () {  
  71.       
  72.     }  
  73. }  
阅读(3490) | 评论(4) | 转发(0) |
给主人留下些什么吧!~~

LBW112019-06-15 17:42:50

你好,我们公司最近要做一个动态生成地形的需求,我是一个新手完全懵逼,我想问一下,Unity生成地形需要那些数据,数据格式是什么格式!麻烦你告诉我一下,不胜感激