前言
最近出于興趣想自己做一個2D的遊戲,因為有着C#的基礎,是以決定使用Unity3D來做。
之前對于Unity3D其實了解不多,不過看了一些Unity3D的視訊和官方文檔後,暫時做起來也沒遇到什麼太大的困難。
本篇部落格要說的是Unity 2018.3新增的一個東西——Isometric TileMap,一般用于做一個2.5D的地圖。

這個東西官方文檔講的并不詳細,并且有些配置完全沒有說出來,導緻始終無法達到預期效果。
國内的各種中文社群和問答網站都沒有這方面的資料,最後還是在Unity的英文社群找到了一篇答案才有了進展:參考連結。
但是即使按照這篇答案中的方法進行操作,在我這裡依然沒法成功實作這個2.5D的地圖。
後來自己慢慢摸索才最終實作,是以特此記錄下實作的步驟。
導入圖檔生成紋理圖檔
如果将使用TileMap畫地圖比作給牆貼瓷磚,那麼首先我們需要為瓷磚設定不同的花紋,是以我們要導入一張圖檔作為花紋。
導入圖檔生成紋理圖檔後,需要将其紋理類型設定為Sprite (2D and UI),因為Tilemaps不支援其它的紋理類型。
注意到紋理屬性中的Pixels Per Unit (PPU),它的值預設為100。
這個屬性很關鍵,它決定了這個紋理圖檔在Unity中顯示時,1個Unity的單元顯示多少個像素。
也就是說一張400 X 200的紋理圖檔在Unity中,相當于4*2個Unity單元。
建立瓷磚
紋理就是一個花紋,不可能将花紋直接花在牆上,我們需要根據花紋生成不同的瓷磚,然後再将瓷磚貼到牆上,Tile就是我們的瓷磚。
通過Assets > Create > Tile生成一個Tile檔案,然後将之前導入的紋理圖檔與Tile檔案關聯。
建立Isometric Tilemap
要貼瓷磚還需要一面牆,而Isometric Tilemap就是我們的牆。
使用GameObject > 2D Object > Tilemap,建立一個帶有一個Tilemap子節點的Grid對象。
這個Grid對象的Cell Layout選項有我們發現關于Isometric Tilemap有兩個,一個是Isometric,而另外一個是Isometric Z As Y。
Isometric實作的是相當于一個地形一樣的東西,但是想要在這個地形上放上房子和樹木之類的,那麼需要設定為Isometric Z As Y。
在這裡我們看到還有一個Cell Size的設定,我在這裡設定為 X:1,Y:0.5,Z:1。(請注意,這裡的Z的大小務必為1,否則同樣無法再地形上放置房子)
Cell Size中的X為1,表示一個Unity的單元格中X的長度相當于多少個Unity單元。
導入一張400 X 200的紋理圖檔,它的PPU為100,那麼相當于需要4 X 2的Unity單元。
因為我們這裡講CellSize的X與Y設定為1和0.5,是以這張紋理圖檔在TileMap中的顯示占4個單元格。
而對于Grid下的Tilemap對象,我們隻需要修改一個屬性,即将Tilemap Render的Mode改為Individual。
這麼做的原因是隻有在Individual下,Scene視圖中Tilemap的各個Tile間才能正确排序。
如果是Chunk模式,不同的Tile在繪制時會出現下面這種遮擋的現象:
不過在我們打包時,還是需要将Mode改為Chunk,因為Chunk會按位置對Tiles進行分組,并将它們的Sprite一起批處理以進行渲染,這樣會提高性能。
另外在Chunk模式下,還需要将不同的Sprite放到一個Sprite Altas中,這樣它們才能正确排序。
因為這篇部落格的主題不是這方面是以隻是捎帶提起,具體如何使用Chunk模式可以查詢官方文檔,這裡不再贅述,先将Mode設定為Individual即可。
建立Tile Palette
有了瓷磚和牆,那麼我們還需要一個裝瓷磚的箱子。
這個瓷磚箱裝着各種各樣的瓷磚,當我們貼瓷磚時,就從這個瓷磚箱中取出來用。
Tile Palette就是我們瓷磚箱。
使用Window > 2D > Tile Palette,打開Tile Palette視圖。
點選Create New Palette建立一個Tile Palette,請保證這個Tile Palette的屬性和Isometric Tilemap的屬性比對,即:
- Cell Size為Manuel,值為 X:1,Y:0.5,Z:1
- Grid為Isometric Z As Y
如果你的圖檔是矩形圖檔那麼就是,那麼這裡的Y為0.5,如果基于等距投射的圖檔,那麼Y為0.57735。
建立了Tile Palette後,我們将之前導入的Tile檔案拖動到Tile Palette上,也就相當于将瓷磚放到了瓷磚箱中。
如果拖動紋理圖檔到Tile Palette上,也會自動生成一個Tile檔案,這樣友善得多。
開始繪制Tilemap
貼瓷磚就是從瓷磚箱中選擇瓷磚,然後貼到牆上。
而繪制地圖,就是在Tile Palette中選擇不同的Tile,然後標明Active Tilemap為指定的TileMap後就可以繪制了。
但是當我們準備畫圖的時候發現,一個Unity單元格實在太小了,就相當于一個像素那麼大。
這裡可以通過設定TileMap對象的scale,将其X和Y放大100倍來處理。(當然也可以通過同時調節Grid的Cell Size的X為100,Y為50,然後再将圖檔的PPU從100改為1)
此時可以看到我們的Tile大小正好合适。
那麼我們可以在兩個單元格内繪制不同的Tile,但是這裡注意到,Tile之間的遮擋存在問題。
解決Tile間的遮擋問題
上面Tile間的遮擋問題,我通過之前提到的Unity英文社群的參考連結解決了。
操作就是通過Edit > Settings > Graphics,修改Transparency Sort Mode為Custom Axis,并将其值設為X:0,Y:1,Z:-0.49。
不同Z Position下Tile的繪制
上面我們實作了基本地形的繪制,現在我們需要在地形上面繪制房子。
之前我們繪制Tile時,Tile Palette的Z Position為0。
現在我們需要在地形上繪制房子,那麼就需要調高Z Position,将Z Position設為1。
繪制後發現遮擋順序不對,咱們的Z Position為1的房子竟然被Z Position為0的地形給遮擋了。
到這裡參考之前的文章也沒辦法處理這個事,沒有任何文檔和資料有關于這個事情的處理。
我這裡也糾結了很久,搞了一兩個晚上都沒搞出來,最後直接加了幾個QQ群,把問題甩在那裡,然後打Dota2去了。
而果然指望别人也不怎麼靠譜,結果最後還是自己去研究。
雖然不清楚内部工作原理,但是按照排除法去想了一下相關的幾個設定點,問題應該就是出現在透明度排序那裡。
于是調節XYZ這三個值,發現将Z進一步調小到-26後就沒有問題了,雖然不知道發生了什麼,但是終究是搞定了。
總結
不知道為什麼最後一個那麼大的坑在官方文檔上完全沒有提及,而且這個功能從這個角度來看,不像是完全做完了的樣子。
希望我的這篇部落格對後來的趟坑者有用吧,當然如果有用也别忘了點個贊。
如文中有謬誤,還望不吝賜教。
PS:
自己建了一個QQ群328544641,用于Unity2D技術的學習交流群,裡面暫時就我一個人。
如果您對Unity的2D技術有興趣,可以互相學習交流。
人不在多,隻希望進群的人可以得到自己想要的答案,也同樣希望您能在了解的情況下給予一些Unity菜雞幫助,比如身為菜雞的我。