之前我們一起學習瞭如何使用Navmesh組件來實現最基本的角色自動尋路。今天我們再繼續深入探索Navigation組件的高級功能。在本文中,你將瞭解到如何在兩個隔離層自動生成尋路網格?如何手動指定尋路網格的路線?以及尋路網格層的應用。(本文所用到的模型皆來自Unity3d官網)。
(轉載請註明原文地址http://blog.csdn.net/janeky/article/details/17492531)
- 隔離層自動生成尋路網格
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腳本
- 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");
- }
- }
- }
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.點擊任意的位置,可以看到角色都能自動尋路過去效果圖
- 手動指定尋路網格方向
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
- 尋路網格層的應用
玩過“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的座標,可以看到他們沿着不同的路徑去目標點,一個走上層路線,一個走下層路線了。
效果圖
- 動態改變尋路網格層
在遊戲中,我們很多時候都是需要根據不同的條件,選擇不同的尋路路徑。
1.在scene3.unity基礎上做一下修改。只保留一個角色
2.新增兩個按鈕,“走上層”和“走下層”,在遊戲運行時,可以改變Agent的尋路層。
- //動態設置尋路路徑層
- 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;
- }
- }
//動態設置尋路路徑層
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.重新點擊尋路,可以看到,選擇不同的尋路層,角色的尋路路徑也不同
所以上層的mask = Default(1)+Blue(128) = 129,下層的mak = Default(1)+Red(64) = 65
- 總結
- 源碼地址
- 參考資料
2.http://liweizhaolili.blog.163.com/
3.http://game.ceeger.com/Components/class-NavMeshAgent.html