2014年11月25日 星期二

Unity:製作雷達小地圖

在許多遊戲中,都會需要小地圖導引,使玩家可以在不切換畫面的情況下確認本身的位置及方向,做得精細一點的,還可以標示週遭的敵人、寶物、NPC、任務等,通常這種小地圖在 Unity 中,只需要多建立一個 Camera 並調整 Depth 以及 Viewport Rect 欄位的值,使其產生子母畫面的效果即可,但有時候為了整體畫面設計以及更舒服的視覺效果,可能需要圓形或特殊形狀的小地圖,那麼就需要一些特殊的處理。


從 Unity 官方範例 Bootcamp,可以看到一個圓形的雷達 UI,會依照人物的移動改變這個 UI 的內容,圓形地圖週邊有點淡淡的半透明往外淡出,這樣的小地圖就比單純矩形的子畫面小地圖要漂亮多了,那麼這種地圖該如何做呢?解析這個範例之後,得到的結論,必須先做一些準備:
  • 一張完整的小地圖圖片。
  • 做為地圖遮罩用的模型。
  • 做為遮罩用的Shader。
  • 裝飾小地圖週邊的圖片。
其中最重要的部分在於遮罩的部分,所以我們必須製作一個中間簍空的平面模型,只要被此模型擋住的地圖將不會顯示在畫面上,而這個模型則需要一個特殊的 Shader,另外,被遮擋的地圖本身所使用的 Shader 也必須要能影響其 Alpha 通道。

首先,我們需要自行製作一個簡單的 Shader,在 Project view 使用 Create 選單建立 Shader,並開啟它將內容改為以下的代碼:

Shader "Custom/MaskMap" {

    SubShader {

        ColorMask A

        Pass{
        }
    }
}



接下來就開始製作雷達小地圖:
  • 從選單列的 GameObject > Create Other > Quad (或 Plane)建立一個簡單的平面,將含有小地圖 Texture 的 Material 賦予給它,這個 Material 的 Shader 建議使用 Unlit/Transparent,最後將該 GameObject 命名為 SmallMap。
  • 自行製作中間簍空的平面模型並拉至場景,擺放於 SmallMap 的前面,並建立 Shader 為 Custom/MaskMap 的 Material 賦予給它,最後將它的 GameObject 命名為 Occluder。
從 Scene view 就可以看到 SmallMap 被 Occluder 遮擋。
  • 與 SmallMap 相同建立一個簡單的平面,將含有地圖外框圖 Texture 的 Material 賦予給它,這個 Material 的 Shader 同樣建議使用 Unlit/Transparent,並將其擺放至 Occluder 之前,最後為該 GameObject 命名為 SmallMapOutline。
SmallMapOutline 放在 SmallMap 及 Occluder 前面。
  • 選取 SmallMap、Occluder、SmallMapOutline 三個 GameObject,並將它們的 Layer 設置為 UI。
把 Layer 設置為 UI。
  • 選取場景中的 Main Camera 並在 Inspector view 將 Camera component 的 Culling Mask 欄位中的 UI 選項取消勾選。
使 Main Camera 的 Culling Mask 欄位不選取 UI。
  • 從選單列的 GameObject > Create Other > Camera 建立第二個鏡頭並為其命名為 SmallMapCamera,將 SmallMapCamera 放置於 SmallMapOutline 之前並轉向面對 SmallMap、Occluder、SmallMapOutline 三個 GameObject,接下來將 SmallMapCamera 的 Camera component 中的 Clear Flags 欄位設置為 Depth only,Culling Mask 欄位只勾選 UI,Projection 欄位改為 Orthographic,Depth 欄位設置為大於 Main Camera 的 Depth 欄位值。
SmallMapCamera 放在最前面並面向三個 GameObject。
設置好 ClearFlages、Culling Mask、Projection、Depth 欄位。
完成以上動作之後,應該就能在 Game view 看到圓形的小地圖以及地圖外框,接著再調整各個 GameObject 到適當的位置,以及調整一下 SmallMapCamera 的 Camera component 的 Size 欄位以及 Clipping Planes 欄位,就算完成小地圖的製作了。至於,玩家角色移動時,SmallMap 應該如何配合移動,由於每個遊戲不同,相對的換算方式也不同,就不在此多做討論了。
在 Game view 看到完成的雷達小地圖。
其實,這種做法有些缺點,例如,能被 Occluder 遮擋的 GameObject 都必須是有 Alpha 的 Shader,如果小地圖中還想要標示更多的東西,那麼每個 GameObject 就都必須使用有 Alpha 的 Shader;另外,由於被遮擋的邊緣不能漸層淡出,所以才需要再疊上 SmallMapOut 的物件,以免小地圖邊緣太銳利而影響美觀,所以在畫面 UI 的設計上就有些微的限制必須要注意。如果不被這些缺點困擾,這種做法也是個相當簡單的應用,不過,應該還有其他更好的方法可以用來製作小地圖,就留待大家去發掘了。

P.S. 使用 Unity 版本為 4.5.5f1。