跟我一起用unity做小地圖!

lol的小地圖

lol的小地圖

轉載爬蟲請自重,未問先轉沒排面

不愛多做鋪墊,小地圖對於一些遊戲來說多重要大家都懂,不然你也不會來看我這篇文章的,對不對?

話不多說,開搞!

一、主體功能

一般來說,遊戲裏的迷你地圖都是平面的。但是,默認的攝像機模式,即perspective(透視),是得不到這樣的效果的。那怎麼辦?使用orthographic(正交)模式就好啦。

修改後,控制視野的參數由Field of View變成了Size

選擇性顯示

如果把遊戲中的所有東西都在小地圖上渲染一遍,難免顯得雜亂,失去了小地圖的簡明扼要這個特點。那怎麼辦呢?

可以選擇使用Layer(圖層)來實現選擇性顯示。即給需要顯示的物體加上特定的圖層,這樣的話,就可以在小地圖裏只顯示具有指定圖層的物體啦。

最簡單的做法,給要顯示的物體加上圖層showInMiniMap,只在迷你地圖中渲染這些物體就可以了。但是呢,我不會這麼做的...因爲我衡量了一下,其實大部分物體都是要渲染的,所以...你懂得,我們給無需渲染的物體加上圖層hideInMiniMap,然後過濾掉他們就好了!

這個 showInMiniMap後面還有用處。

引申:給NPC加上特定標記

舉一反三是一個很好的習慣,相信有些機智的小夥伴已經能想到了。如果給特定的NPC加上特定的圖層,是不是就可以在地圖上顯示不同的標記呢?

比如:

  • 敵人:紅色點點
  • 自己:綠色長三角(三角尖指向當前朝向)
  • 商店老闆:金袋icon
  • 裝備升級:劍盾icon

一種很簡單的做法,就是給這些物體加上相應的icon模型,位置就和本物體重合,然後將icon模型設置爲showInMiniMap,然後在主攝像機裏剔除,讓他們不會出現在視野裏。然後給本來模型,加上hideInMiniMap圖層,這樣他們就不會出現在小地圖了。

如此一來就實現了遊戲視圖裏看到的是模型,而小地圖裏看到的是icon了。

二、進階功能

給小地圖加個圓框

讓小地圖和主角一起轉動

transform.rotation = Quaternion.Euler(
    new Vector3(
        transform.rotation.eulerAngles.x,
        playerTransform.rotation.eulerAngles.y,
        transform.rotation.eulerAngles.z
    )
);

加上指南針

有些人,看到小地圖,就想到圓;看到圓,就想起轉動;看到轉動,就想起指南針。 —— 魯迅

沒錯,接下來我們就做指南針。

讓指南針更逼真

現實中的指南針並不會一瞬間指向南的,而是有個慢慢晃動校準的過程,我們也可以做出這樣的效果來!

compass.rotation = Quaternion.Lerp (
    compass.rotation,
    Quaternion.Euler (0, 0, playerTransform.rotation.eulerAngles.y+compassOrientationOffset),
    Time.deltaTime * compassRotationSpeed
);

Quaternion.Lerp 是個非常棒的函數, 處理旋轉問題呱呱叫!比如說,120度轉到-120度,我們無需自己判斷是順時針轉動240度,還是逆時針轉動120度,這個函數會自動幫您選擇最小的度數(120度)轉過去。

三、完善功能

爲啥是先講進階,後講完善呢?

處理小地圖燈光

如果你的遊戲世界裏存在白天黑夜循環,比如dota2,你又不希望你的小地圖黑夜比白天黑很多,頂多視野變得狹隘點。那麼就需要給小地圖設置另一套燈光渲染。

void OnPreCull (){
    foreach(Light l in minimapLightsNotVisible)
        l.enabled = false;
    foreach(Light l in minimapLightsNoShadows)
        l.shadows = LightShadows.None;
    foreach(Light l in minimapLightsVisible)
        l.enabled = true;
}
void OnPostRender(){
    foreach(Light l in minimapLightsNotVisible)
        l.enabled = true;
    foreach(Light l in minimapLightsNoShadows)
        l.shadows = LightShadows.Soft;
    foreach(Light l in minimapLightsVisible)
        l.enabled = false;
}

處理在屋子裏情況

這裏應該要分好幾種情況,先說兩種:

  • 低矮的屋子
  • 高樓

首先,我們進了矮屋子咋辦,因爲小地圖是頭頂的攝像機渲染的,所以攝像機會被屋頂擋住。我在小地圖裏只能看到一個屋頂。這個根據業務需要,解決方法如下:

  • 你可以選擇進入某個屋子後,就不渲染這個屋子的屋頂了(需要在代碼中做相應的控制),這貌似是很多生存類遊戲的解決方案。
  • 也可以選擇就是要顯示屋頂,都進了屋子裏,這個屋子就是個地標,還要啥小地圖?

我們這裏先提供第一種解決方案的實現。

然後我進了一個高樓咋辦?如果我停在1樓,因爲攝像機高度是有限的,它很可能停留在3樓或者4樓,那就很詭異了,我在1樓某個屋子走來走去,攝像機卻顯示了3樓空無一人的場景。這顯然是無法接受的。

進入地下城

下面就是個特殊例子了,進入地下城或者蜿蜒曲折的山洞咋辦?

衆所周知,地下城都是帶“蓋子”的,天生帶屋頂,如果你還是把攝像機放在天空,就有點像進入高樓那種情況了,詭異。而且地下城裏高高低低,上上下下,攝像機卡在隔壁房間,甚至卡在你根本沒設計的牆外世界,看到外面詭異的天空盒子,這就很像某部科幻電影裏的場景了...這是完全無法接受的!

怎麼辦呢?碰撞檢測吧!從攝像機發射一根射線到人物,如果中間碰撞了設定爲牆壁圖層的物體,就是穿牆了,這時候就把攝像機前移到碰撞點前面一些的位置,這樣就不會有問題了。

下面我們開始實現。

結語

其實小地圖上可以玩的花樣肯定還有很多,這些就等各位大佬慢慢挖掘,自己實現啦。也歡迎大家不吝分享自己的經驗,一起進步~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章