傳統的FP Dungeon Crawler(FPDC)撇開玩家的視角,玩家的移動實際上是以格狀的方式進行,一次一格的方式進行移動。利用Unity本身3D的優勢,可以直接以3D方式進行地城場景設置。
先利用方塊進行模擬地城環境的牆和玩家角色。日後雖然會利用自動生成的方式進行,但仍是有幾關會是固定的埸景,且前期開發時,固定地形較容易進行測試。
利用3D的場景設置是很方便的,但仍需要有和Roguelike遊戲相仿的格狀場景來進行移動。從這個移動的機制來看,FPDC和Roguelike是很像的,不同點在於FPDC以第一人稱方式進行場景移動探索,但Roguelike則是上視角的方式進行。
基於格狀移動是基本的一個環節,要用個方式將目前的3D景進行轉換成2D格狀地圖進行使用。
最簡單的方式,就是利用Raycast從上方投射下來,如果沒有碰到任何場景物件(又或是只碰到地板)則表示該處可通行,若是碰到了障礙物(牆壁等)則記錄該處不可走。待完成整個Raycast掃瞄後,將其記錄下來的格狀地圖用以後續的尋路、移動。
說到尋路(Pathfinding),自然地就會想到在Unity裡有現成的Pathfinding機制,然在Unity的環境中,只提供了NavMesh的Graph,對於這個格狀移動並沒有太大的幫助。還好在Unity Asset Store(UAS)裡有個非常知名的尋路外掛可以協助這塊。
UAS中的版本還停在4.2.15版,但實際上A★的開發者已於2019年就開始著手4.3.x版本撰寫,主要的修改是搭配Unity ECS使其Search效能更佳。但Unity ECS本身一直都還沒有到穏定的階段,所以A★的開發者在UAS裡並沒有釋出4.3.x版,若是有從UAS裡購買4.2.x版的使用者,可自行於其官網下載4.3.x版。
利用A★裡的Grid Graph再進行一些設定
進行場景Scan時則可以發現,A★就是利用之前提及的Raycast做轉換,將現有的場景轉換成內部的格將資料。
地城的地版很寛敞時,沒有出界的偵測
將場地的地板縮小後,沒有額外定義阻擋物時,會全部都被判定成可以移動的區域
加入了阻礙物後,再次掃瞄才會有想要的結果
可以從A★的掃瞄結果了解到在A★自身的資料裡已經有整個場景的格狀資料,接下來就是抽取出來進行使用。
程式碼部份最主要的片段
astarPath.Scan();
// Get the nodes in the first graph
astarPath.graphs[0].GetNodes(gn => {
if (gn is GridNode gridNode)
{
// Use casted grid node instead of original graph node
}
});
先進行Scan的動作,讓整個Graph建立起來。再進行每個Grid Node的查詢,看玩家目前的位置是對應到哪個Gird Node。
在接合A★之前,先進行移動的行為製作。雖然是以手機平台為主,但開發期間能夠利用鍵盤進行移動也是方便於除錯的,還沒有進入UI之前,仍以Keyboard Input進行基本移動的操控。
利用Input System進行Action設定。為了呈現FPDC的移動機制,四方向移動加上左、右旋轉是必要的基本控制。
接收到Movement Input後,利用Visual Scripting(VS)處理移動行為。這裡的移動是沒有考量到障礙物的情況下,可以自由的做四方向移動。
加上了處理旋轉後的行為
在移動時用Translate進行,一但旋轉後其前後左右的定義也不用做修正就是正確的。
自由移動的部份完成後,接下來就是要和現有的Grid Graph做接合,進行移動時的檢查,並決定是否可以完成移動。
這套A★在做格狀時,如果是四方向,則依順序為下右上左,也就是說0代表負Z的方向,1代表正X的方向,2代表正Z,而3代表負X。
不過自己的習慣是前右後左,為了避開運算向量的麻煩,則利用表格存下玩家面向按下的四方向輸入會對應到A★哪個方向。其實已經是用了vs,遊戲類型又是回合式移動,效能並不是最優先考量,用表格的方記錄也只是避免複雜的運算。
修正過後的VS
如預期般的方向的轉換和移動都是正確的,但這裡有幾個問題要記錄下來
對於直接在Code進行位置改變這件事,如果是平常純以Code方式處理並無不妥,不過用了VS,就表示可以更有彈性的在VS裡進行。
若是直接引用A★的Node資料可以用這個API進行
var gridNodeBase = _atGridNode.GetNeighbourAlongDirection(moveDirection);
先記錄下來,之後再找時間調整。