如何製作遊戲 能力雷達圖 (unity 多邊形繪製的應用) 心得分享

今天跟各位分享如何製作遊戲中常看到的能力雷達圖
 

直接開門見山來說, 我想到的做法是後面一張雷達圖sprite當背景, 然後根據不同的數據值繪成多邊形

Unity的範例

所以這一題可以化簡為 如何繪製多邊形mesh...這邊unity官方說明文件提供了一個範例
如何繪製三角形的mesh :
所以要在unity繪製mesh的步驟流程是 :
  1. 新增一個 MeshFilter 元件
  2. 準備 Vertices array, 也就是多邊形的頂點座標
  3. 準備 UV array,這目的是描述mesh頂點如何對應UV
  4. 準備 triangle index array, 這個概念是mesh是可由多個三角面組成, 透過這個array依序將三角點描述出來讓GPU知道如何繪製mesh (Note : 這個index array 有順序的規則,不照規則會描繪不出來mesh,算是需要注意的地方)
  5. 最後將此 mesh 指定到 MeshFilter.mesh 變數,即可繪出指定的mesh
OK, 我們就來實做看看如何繪出多邊形吧!
 
首先,我們先準備Verices (多邊形頂點座標), 這邊我運用了單位向量旋轉的觀念,依序抓出我要的頂點
我們知道多邊形的內角和為360度, 舉六角多邊形為例的話, 可以分為360/6 = 60度為一次的旋轉
所以我們對 Vector.up (0,1,0) 這個單位向量做每次60度角的旋轉,就可以得到六個端點座標了!
但是我們不是要畫正六邊形, 能力雷達圖表示法是每個端點代表幾級能力,所以我們假設分五個等級能力好了
那就是把每個旋轉後的向量再乘以一個scale, ex. 能力2級就代表 scale = 2/5
有能力雷達圖概念的多邊形頂點就被我們抓出來了

相關的Code 如下 :

接下來,創建UV array. 這邊因為不需要圖片當UV 去mapping多邊形頂點,
所以用最簡單無腦的mapping法:
偶數頂點map UV(0,0) 位置, 奇數頂點map UV (1,1)位置
再來是建立描述三角面的array,描述三角面就是用一個int array來描述一個mesh是由長怎樣的三角形組成的
我們再以正六邊形為例
藍色數字為我們抓取頂點的編號順序,我們可以這樣描述三角面 : 

 

第一個三角形為 0,1,2
第二個三角形為 0,2,3
第三個三角形為 0,3,4
第四個三角形為 0,4,5
以上是對每個三角形作逆時針方向描述
如果我們改為
第一個三角形為 0,2,1
第二個三角形為 0,3,2
第三個三角形為 0,4,3
第四個三角形為 0,5,4
對每個三角作順時針方向描述的話,一樣是合法的描述,但是被渲染的面會是反面端

 

寫成支援多邊形的code,我就參考網路上一位作者的一小段

不過很可惜,這種描述三角面的方法是有問題的! 問題出現在凹邊形上!
舉個例子 :
我們將頂點等級設定依序是
頂點0 : 5級
頂點1 : 1級
頂點2 : 4級
頂點3 : 4級
頂點4 : 1級
頂點5 : 3級
 
正確的圖想像應該是這樣

不過,輸出是這樣 :

為什麼會這樣呢?

這是因為頂點1是已形成凹面了,可是我們還是描述有個三角面在那

其實這樣的做法無法解決多邊形凹面的繪製.

 
所以最後換成另外一種作法 : 將原點算是一個頂點, 作出六個mesh面,每面mesh就只有一個三角面
這樣算是通解不管怎樣設定都能正確繪出了.

好啦! 最後一步就是設定mesh,將此mesh assign到mesh filter 裡面去!!

最終結果

最後, 讀者會注意到黃線的部分,那是mesh之外的 linerenderer 繪製,不過頂點概念跟mesh繪製是一樣的.
這個請讀者自行在release 的script中看了,就不再說明了.
 
心得 : 用script畫這樣的mesh算是簡單入門, 做出來的東西也實際可用.
unity官方文件裡在這邊的描述不是很讓新手容易上手,比如說文件裡這段

我點 Procedural example project 進去, 是個 asset store free package

下載後,執行其中一個scene

這是用script 編輯mesh 做出來的東西,很酷炫,但......基本概念沒有,還是不容易上手哇....
 
最後,感謝大家能看到最後, package 可在github上下載