1. 程式人生 > >Unity 執行時動態編輯Terrain(一)介紹

Unity 執行時動態編輯Terrain(一)介紹

Unity自帶了一個非常強大的地形編輯器,但是總結起來也有一些缺點

1.不能在執行時編輯

2.不能跨多塊地圖編輯

正好近期的專案中需要在執行狀態下實現超大地形和跨多塊地形編輯的功能,於是花了一段時間研究了地形的動態編輯。Unity本身雖然無法為我們實現執行時編輯,但是TerrainData類的強大API彌補了這一缺點,從這篇文章開始會逐步構造一個動態修改地形的工具類,實現了地形高度編輯,樹木編輯,細節編輯,貼圖編輯以及自定義筆刷。後面將分成幾篇文章分別講解,最後會提供原始碼的下載。這一篇對我們需要處理的地形資料進行介紹。

1.TerrainData

在場景中建立一塊地形時,Unity會幫我們自動建立一個TerrainData檔案,這個檔案展開後會發現有一張含有RGBA四個通道資料的貼圖。我們地形資料實際上也就時這張貼圖的資料。由於RGBA四個通道的取值範圍時[0,1],所以我們在給地形設定高度圖,透明通道圖等資料時,也都是將其實際值轉化為0到1的比例值進行設定。

下面是隨便建立的一塊地形以及其TerrainData的貼圖,由此大致可以猜出RGBA四個通道每一個都代表一種型別的地形資料。

 

2.HeightMap

Unity的高度圖是一個第一維和第二維長度(必須是2的n次方加1,加1是為了連線相鄰的地形塊)相等的二維陣列,取值範圍是0到1。用這個值乘上地形的最高高度terrainData.size.y就是這個點在世界空間中的實際高度。高度圖的第一維對應世界座標系中的z軸,第二維對應x軸,這一點與我最開始想的正好相反。Terrain也是一個Mesh網格,二維陣列的資料對應的也就是這些網格頂點的高度資料。對Unity動態繪製網格不熟悉的可以自行百度,資料很多,這裡我推薦一個國外大神的網站,很多國內資料的“原創”部落格都搬運自

大神的網站,裡面有不少好東西

 

3.AlphaMap

在Unity的地形編輯器上,我們在編輯地形貼圖的時候,需要在面板上新增貼圖,Unity2018之前,這個貼圖資料其實是SplatProotype,到Unity2018後官方做了更新,變成了TerrainLayer。在我後面的文章中對這一點做了適配。

TerrainLayer中包含了漫反射貼圖、法線貼圖等資料,我們在修改地形之前,需要建立一個TerrainLayer的陣列並賦值。

AlphaMap是一個三維陣列,第三維表示層級,也就是我們需要在初始化中設定的TerrainLayer。AlphaMap第一維和第二維的長度設定為2的n次方,其索引代表的是一個小方塊的貼圖。三位陣列的取值範圍一樣是0到1,值的含義的是當前層級貼圖所佔的比例。一個小方塊可以設定不同的Layer,Unity會按照你設定的比例自動進行融合。

4.DetailMap

DetailMap在編輯之前也需要初始化一個數組DetailPrototype。

同高度圖一樣,DetialMap也是一個二維陣列,但是它是一個int型的陣列,其取值範圍也不再是0到1。其值的含義是在索引所對應的小方塊上對應草的數量。

5.Tree

上述幾個資料的設定都是在TerrainData中進行的,樹木的設定移到了Terrain中,並且F12跟蹤到Terrain類後並沒有發現刪除樹木的API,後來看了一下Terrain的原始碼,發現刪除樹的方法是受保護的,外界無法直接呼叫,所以我在工具中用了反射,後面的文章會細說這一部分。