unity尋路

    最近被尋路給搞蒙了,由於我想做汽車的尋路,而且汽車速度什麼的都定義好了,而unity自帶的組件nav mesh agent自帶了一些速度之類的值,搞得我很不開心,雖然值可以設爲0,但後來還是發現有很多問題。不過,這個自帶的功能還是很不錯,可能不適合汽車,只對人比較友好,本着學習的態度我認真研究了一下。

    我們都知道,unity常見的尋路算法有:Astar尋路,自帶尋路navmesh,點尋路等等。A*尋路就不說了,早期一般都是用它,算法插件網上都有。unity自帶的這個尋路很有意思,首先選擇window->navigation,然後可以看到檢視板後面多了一個,選擇你要烘培的靜態物體,一般是地面,道路等等。勾選navigation static,烘培bake意思是被你選擇的地方是可通行的,當然注意下面navigation area,裏面有walkable,還有not walkable。勾選完之後就可以點擊bake了,還有一些參數啥的,可以在API上去查查,可以多次bake哦。成功之後你可通行區域變成這個樣子,可以看到變成了淺藍色。

     然後你需要在尋路者的身上掛一個Nev mesh agent組件,如圖:

    

 看到左上角那個人了嗎,不是我要吐槽它啊,可能就是爲主角是人量身定製的,它是一個膠囊體,注意的是你需要調radius和height把尋路物體完全包住。然後設置一個尋路對象就可以尋路了,是不是很簡單。自帶的組件還有一個重要功能就是動態尋路,動態尋路意思是你在尋路的過程中突然增加了一個障礙,遊戲中很常見的。具體做法是在上面基礎上,給障礙物添加一個組件nav mesh obstacle,再掛一個剛體,製作成預製體(就是可以複用的東西),然後把它做成一個在運行時動態Instantiate 實例化出來,尋路網格會重新生成。具體運行時這些組件幫你找到一條最短路徑然後動態避障。當然還有一些別的運用,比如三路小兵分別尋不同的路徑。

    網上看資料的時候發現一位童鞋的例子特別好,值得好好學習。傳送門~還有動態避障再傳送,還有小兵這個,好像他也是轉的,在這裏,感謝各位大佬。

    然後點尋路官方的例子有,但是我感覺太過複雜,後來自己寫了一個很菜的方法,就是汽車一個位置一個位置的去尋,意思我提前定好位置,它只需要一個一個去找就好了。如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using System;
namespace UnityStandardAssets.Vehicles.Car
{
    [RequireComponent(typeof(CarAIControl))]
    [RequireComponent(typeof(CarController))]
    public class WayTrack : MonoBehaviour
    {
        public GameObject obj;
        public Transform[] newposition = new Transform[] { };
        int k = 0;
        float dis;
        // Use this for initialization
        void Start()
        {

            obj.transform.position = newposition[0].position;

        }
        // Update is called once per frame
        void Update()
        {
            Vector3 m = obj.transform.position;
            Vector3 n = this.transform.position;
            dis = Vector3.Distance(m, n);
            if (dis < 2.0f)
            {

                k++;
                k = k % newposition.Length;
                Transform next = newposition[k];
                obj.transform.position = next.position;
                Quaternion shipRotation = Quaternion.Euler(0, 0, 0);
                obj.transform.rotation = shipRotation;
                //  Debug.Log(k);
               
            }
       
            Debug.Log(GetComponent<CarController>().m_Rigidbody.velocity.magnitude*3.6f);

        }
       void OnTriggerEnter(Collider other)
      {
            //   GetComponent<CarAIControl>(). m_CarController.Move(0, 0, -1f, 1f);
            if (other.tag == "stop"&&dis<10)
            {
           GetComponent<CarAIControl>().m_Driving = false;
            }
            else
            {
                GetComponent<CarAIControl>().m_Driving = true;
            }
      }
  
    }


}

這個和我前面翻譯的官方例子是一個系列,可以看出我update中每幀都在計算它與下一個位置的距離,當小於2時,目標位置會跳到下一個位置。然後添加了接觸器,當接觸到tag是stop的物體且dis小於10,汽車會剎車。後續還會有很多功能,我會一一分享。

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