• 高度地形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!”

  • 相关阅读:
    android原子
    android进程优先级
    Android 的cyclicBarrier
    android中运用CountDownLatch
    java网络编程长连接的问题
    https
    http 上传文件
    netty4 断线重连
    Linux下高并发socket最大连接数所受的各种限制
    Android Studio NDK及so文件开发
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3093458.html
Copyright © 2020-2023  润新知