高度地形Unity3D 通过代码导入自定义格式地形的方法

最近使用开发的过程中出现了一个小问题,顺便记录一下原因和方法--高度地形

    最近有点空闲时间,就打算把以前项目的场景资源转移到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以上。

    最后放上截图一张

    

  高度和地形

    详细的实现代码如下:

    每日一道理
风,渐渐吹起,吹乱了我的发丝,也让我的长裙有些飘动。绿叶仿佛在风中起舞,离开了树,投向了大地,却不知这样会枯萎,我弯下腰,轻轻拾起一片树叶,那非常有序的茎脉,是一种美的点缀。我有些哀叹:绿叶啊,绿叶,你这般美丽地从树上轻轻飘下,随风起舞,却不知已被人称之为落叶!
using UnityEngine;
using System.Collections;
using System.IO; 


public class TerrainLoader : MonoBehaviour {
	
	public string HeightDataFile;
	
	public int MapSize;
	
	public Terrain terrain;
	
	// Use this for initialization
	void Start () {
        // 读取资源
	TextAsset TA =  Resources.Load(HeightDataFile) as TextAsset;
		
       	byte[] buff = TA.bytes; 
        	buff[buff.Length-1] = 0;
		
	float[,] data = new float[MapSize,MapSize];
		
	int index = 0;
	float min = 0;
	float max = 0;
		
        // 将二进制转换为float
	for(int i = 0; i<MapSize; i++)
	{
		for(int j = 0; j<MapSize; j++)
		{
			data[i,j] = System.BitConverter.ToSingle( buff, index );
			index += 4;	
			if(min > data[i,j])
				min = data[i,j];
			if(max < data[i, j])
				max = data[i,j];		
		}
	}
		
        // 计算出地形最大值与最小值的高度差
	float detailHeight = max - min;
		
        // 设置地形的最大高度
	terrain.terrainData.size = new Vector3(512,detailHeight,512);
		
        // 将地形整体上移,消灭负值
	for(int i = 0; i<MapSize; i++)
	{
		for(int j = 0; j<MapSize; j++)
		{
			if(min < 0)
			{
				data[i,j] = data[i,j] - min;
			}
			data[i,j] = data[i,j] / detailHeight;
		}
	}
		 
	// 设置分辨率
	terrain.terrainData.heightmapResolution = MapSize;
		
        	// 导入高度数据
	terrain.terrainData.SetHeights(0, 0, data);
	
	}
	
	// Update is called once per frame
	void Update () {
	
	}
}

    
 

文章结束给大家分享下程序员的一些笑话语录: 一位程序员去海边游泳,由于水性不佳,游不回岸了,于是他挥着手臂,大声求.救:“F1,F1!”

原文地址:https://www.cnblogs.com/jiangu66/p/3093458.html