自動尋路Navmesh基礎入門

自動尋路Navmesh

現在的大部分遊戲都有了自動尋路功能。點擊場景上的一個位置,角色就會自動尋路過去。中間可能會有很多的障礙物,角色會自動繞過障礙物,最終達到終點。使用Unity來開發手遊,自動尋路可以有很多種實現方式。第一種比較傳統的是使用A星尋路,它是一種比較傳統的人工智能算法,在遊戲開發中比較常用到。大部分的頁遊和端遊都用到這種技術。在Unity遊戲也可以用這種技術,Asset Store上面已經有相關的組件了,感興趣的同學可以自己去了解。我在後面有機會再來詳細介紹了。今天我們來學習Unity官方內置的尋路插件-Navmesh。今天先通過學習一個最簡單的例子來入門。

 

 

一個物體只要有了transform就可以使用尋路功能。

•   實例

•               我們要實現一個功能:點擊場景中的一個位置,角色可以自動尋路過去。角色會繞過各種複雜的障礙,找到一條理論上”最短路徑“。

•   步驟

•               1.創建地形

•               2.添加角色

•               3.創建多個障礙物,儘量擺的複雜一點,來檢查Navmesh的可用性和效率。

•               4.選中地形,在Navigation窗口中,設置Navigation Static

•               5.依次選中障礙物,在avigation窗口中,設置Navigation Static

•               7.Navigation窗口中,選擇Bake(烘焙)界面,點擊Bake按鈕,進程場景烘焙,就可以烘焙出尋路網格了

•               8.爲角色添加NavMeshAgent(網格代理尋路)組件。Component->Navigation->NavMesh Agent

9.爲角色新增一個腳本PlayerController.cs,實現點擊目標,自動尋路功能

 

 

相關知識

1.角色身上的Nav Mesh Agent 組件

Radius 半徑: 代理的半徑(僅用於尋路目的,可以跟實際對象的半徑大小不一樣,一般比實際對象的半徑大)。

Speed 速度: 代理可以周遊世界,走向它的目的地的最大移動速度。

Acceleration 加速度: 最大加速度。

Angular Speed 角速度: 最高轉速(度/秒)。

Stoppingdistance 制動距離:制動距離。到目的地的距離小於這個值,代理減速。

Auto TraverseOffMesh Link 自動遍歷OffMesh鏈接:自動移動並關閉OffMeshLinks

Auto Repath 自動重新尋路:如果現有的部分已失效,獲得新的路徑。

Height 高度:代理的高度(用於調試圖形)。

Base offset 基本偏移:碰撞幾何體相對於實際幾何體垂直的偏移。

ObstacleAvoidance Type 障礙躲避類型 :躲避的質量水平。

NavMeshWalkable 導航網格行走:指定代理可以遍歷的導航網格層類型。這個參數很有用,在接下來的實例中可以用到

 

 

 

2.障礙物一定要有Mesh Render,用於烘焙尋路網格。

•   總結

這個實例可以很簡單的讓我們學會如何最基本的使用自動尋路組件Nav。但是,這個組件還提供了更加強大的功能,比如,起始點和目標點中間出現阻斷了,

怎麼辦?在下面的文章中,我們將會繼續探尋其他強大的功能。

實例:

using UnityEngine;
using System.Collections;

public class walk : MonoBehaviour {
    public Animator aa;
    public Camera cc;
    public Vector3 targetposition;
    public NavMeshAgent nav;
    void Start () {
        targetposition=this.transform.position;
        aa=this.GetComponent<Animator>();
        nav=this.GetComponent<NavMeshAgent>();
    }
    

    void Update () {
        nav.SetDestination(targetposition);
        if(Input.GetMouseButtonDown(0)){
            aa.Play("Skeleton_walk");
            getpoint();
        }
        if(nav.remainingDistance<0.3f){
            aa.Play("Skeleton_Idle");
            nav.Stop();
        }
    }

    void getpoint(){
        Ray ray;
        RaycastHit hit;
        ray=cc.ScreenPointToRay(Input.mousePosition);
        if(Physics.Raycast(ray,out hit)){
            if(hit.collider.gameObject.tag=="Road"){
                //Debug.Log(hit.point);
                targetposition=hit.point;
            }
        }
    }
}

發佈了24 篇原創文章 · 獲贊 3 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章