Unity手遊之路自動尋路Navmesh之高級主題

之前我們一起學習瞭如何使用Navmesh組件來實現最基本的角色自動尋路。今天我們再繼續深入探索Navigation組件的高級功能。在本文中,你將瞭解到如何在兩個隔離層自動生成尋路網格?如何手動指定尋路網格的路線?以及尋路網格層的應用。(本文所用到的模型皆來自Unity3d官網)。

(轉載請註明原文地址http://blog.csdn.net/janeky/article/details/17492531

  • 隔離層自動生成尋路網格
(源碼scene1.unity)
1.創建Plane實例P1,P2,兩者之間出現一條鴻溝。直接控制角色位移是無法通過的。
2.打開Navigation窗口,分別選中P1,P2,分別設置Navigation Static 和OffMeshLink Generatic

3.保存場景,點擊場景烘焙按鈕Bake。結束後我們可以看到P1,P2除了自身生產尋路網格外,它們直接還生成了連接紐帶。
4.添加角色模型Solder,爲其添加NavMeshAgent(Component->Navigation->NavMeshAgent)
5.給Solder添加PlayerController腳本
  1. using UnityEngine; 
  2. using System.Collections; 
  3.  
  4. public class PlayerController : MonoBehaviour 
  5.     private NavMeshAgent agent; 
  6.  
  7.     public bool setAgentWalkMask;//是否需要動態修改尋路層,在scene4的實例中要用到 
  8.  
  9.     void Start() 
  10.     { 
  11.         //獲取尋路組件 
  12.         agent = GetComponent<NavMeshAgent>(); 
  13.     } 
  14.  
  15.     void Update() 
  16.     { 
  17.         //鼠標左鍵點擊 
  18.         if (Input.GetMouseButtonDown(0)) 
  19.         { 
  20.             //攝像機到點擊位置的的射線 
  21.             Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition); 
  22.             RaycastHit hit; 
  23.             if (Physics.Raycast(ray, out hit)) 
  24.             { 
  25.                 //判斷點擊的是否地形 
  26.                 if (!hit.collider.tag.Equals("Plane")) 
  27.                 { 
  28.                     return
  29.                 } 
  30.                 //點擊位置座標 
  31.                 Vector3 point = hit.point; 
  32.                 //轉向 
  33.                 transform.LookAt(new Vector3(point.x, transform.position.y, point.z)); 
  34.                 //設置尋路的目標點 
  35.                 agent.SetDestination(point); 
  36.             } 
  37.         } 
  38.  
  39.         //播放動畫 
  40.         if (agent.remainingDistance == 0) 
  41.         { 
  42.             animation.Play("Idle"); 
  43.         } 
  44.         else 
  45.         { 
  46.             animation.Play("Run"); 
  47.         } 
  48.          
  49.     } 
using UnityEngine;
using System.Collections;

public class PlayerController : MonoBehaviour
{
    private NavMeshAgent agent;

    public bool setAgentWalkMask;//是否需要動態修改尋路層,在scene4的實例中要用到

    void Start()
    {
        //獲取尋路組件
        agent = GetComponent<NavMeshAgent>();
    }

    void Update()
    {
        //鼠標左鍵點擊
        if (Input.GetMouseButtonDown(0))
        {
            //攝像機到點擊位置的的射線
            Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);
            RaycastHit hit;
            if (Physics.Raycast(ray, out hit))
            {
                //判斷點擊的是否地形
                if (!hit.collider.tag.Equals("Plane"))
                {
                    return;
                }
                //點擊位置座標
                Vector3 point = hit.point;
                //轉向
                transform.LookAt(new Vector3(point.x, transform.position.y, point.z));
                //設置尋路的目標點
                agent.SetDestination(point);
            }
        }

        //播放動畫
        if (agent.remainingDistance == 0)
        {
            animation.Play("Idle");
        }
        else
        {
            animation.Play("Run");
        }
        
    }
}
5.點擊任意的位置,可以看到角色都能自動尋路過去
效果圖


  • 手動指定尋路網格方向
源碼scene2.unity
1.scene1.unity的基礎上,將P1,P2的OffMeshLink Generatic去除
2.在P1上新建一個空的GameObject Start,P2上新建一個空的GameObject End
3.選中start,爲它添加Off Mesh Link組件 Component->Navigation->OffMeshLink
4.設置Off Mesh Link組件的屬性,Start Point 爲 start,End Point爲end
5.烘焙場景。我們可以看到有一條紐帶從start指向end
點擊地圖,可以看到角色如果要跨越P1和P2,一定是沿着我們手動創建的路徑


  • 導航網格障礙物 Navmesh Obstacle
之前我們都是用固定的物體作爲障礙物,然後烘焙場景。Unity還提供了動態的障礙物。任何一個GameObject都可以添加Navmesh Obstacle組件,變成一個障礙物。具體步驟是Component->Navigation->Navmesh Obstacle.它有兩個屬性:半徑和高度,可以設置跟你的物品差不多的體積大小。
  • 尋路網格層的應用
源碼scene3.unity
玩過“3c”,“dota”這類遊戲的同學都知道:地圖上有上中下三條大道,不同的兵可能去的路不同。今天我們也做個類似的實例。
1.新建P1,P2,P3,P4等4個Plane,具體擺設形狀見效果圖
2.在Navigation窗口中,添加兩個層Layers:Blue層和Red層
3.P1,P2的Navigation Layer設置爲Default,P4的Navigation層設置爲Red,P3設置爲Blue
4.添加兩個角色,設置他們的NavMeshAgent尋路層(NavMesh Walkable)。一個將Red層去掉,一個將Blue層去掉
5.點擊P2的座標,可以看到他們沿着不同的路徑去目標點,一個走上層路線,一個走下層路線了。
效果圖


  • 動態改變尋路網格層
源碼scene4.unity
在遊戲中,我們很多時候都是需要根據不同的條件,選擇不同的尋路路徑。
1.在scene3.unity基礎上做一下修改。只保留一個角色
2.新增兩個按鈕,“走上層”和“走下層”,在遊戲運行時,可以改變Agent的尋路層。
  1. //動態設置尋路路徑層 
  2.    void OnGUI() 
  3.    { 
  4.        if (!setAgentWalkMask) 
  5.        { 
  6.            return
  7.        } 
  8.        if (GUI.Button(new Rect(0, 0, 100, 50), "走下層")) 
  9.        { 
  10.            agent.walkableMask = 65; 
  11.        } 
  12.  
  13.        if (GUI.Button(new Rect(0, 100, 100, 50), "走上層")) 
  14.        { 
  15.            agent.walkableMask = 129; 
  16.        } 
  17.    } 
 //動態設置尋路路徑層
    void OnGUI()
    {
        if (!setAgentWalkMask)
        {
            return;
        }
        if (GUI.Button(new Rect(0, 0, 100, 50), "走下層"))
        {
            agent.walkableMask = 65;
        }

        if (GUI.Button(new Rect(0, 100, 100, 50), "走上層"))
        {
            agent.walkableMask = 129;
        }
    }

3.重新點擊尋路,可以看到,選擇不同的尋路層,角色的尋路路徑也不同


看到代碼中的agent.walkableMask = 65和129,大家會比較迷惑,其實尋路層每一層都是2的冪,見下圖

所以上層的mask = Default(1)+Blue(128) = 129,下層的mak = Default(1)+Red(64) = 65
  • 總結
本文將尋路組件的各個細節都做了一次梳理,詳細能幫大家熟練掌握各個特性,在實際項目中根據不同的需求熟練選擇應用相關的特性。接下來我還會有一個更加詳細的實例來貫穿所以的Navmesh特性,敬請期待!
  • 源碼地址
http://pan.baidu.com/s/1jGoLITo
  • 參考資料
1.http://www.xuanyusong.com/
2.http://liweizhaolili.blog.163.com/
3.http://game.ceeger.com/Components/class-NavMeshAgent.html
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章