1. 程式人生 > >關於Unity navMeshAgent自動尋路的停止和更新問題

關於Unity navMeshAgent自動尋路的停止和更新問題

這兩天可把我愁死,明明是一個很簡單的問題,沒有去了解基礎實質,只想著快點做完果然很耽誤事,也是把解決辦法分享出來,辦法很low歡迎交流。

哪個物體需要尋路就在哪個物體上加一個Nav Mesh Agent元件,主要介紹一下steering下的引數,一個是尋路速度,最大的加速度,角速度,以及制動距離。這幾個引數可以讓你的尋路更加的圓滑,推薦大家自己去調的時候用一下。

使用前需要對場景先進行烘焙

在“Window”-“Navigation”,開啟“Navigation”視窗

選中你選則不允許通過的地方,例如我場景中的欄杆等,在選上你可以通過的地方,,在“Navigation”裡選中“Bake”面板進行烘焙

如果不做跳躍的話,Generate offMeshLinks是不用勾選的。

然後就是程式碼部分了(程式碼寫在你需要尋路的物體上)

    private NavMeshAgent man;
    public Transform target;

首先要定義一個NavMeshAgent的變量出來,還有一個目標點的變數。

man = gameObject.GetComponent<NavMeshAgent>();

在start函式中為這個變數賦值,

IEnumerator AINavMesh()
    {


        while (true)
        {
           

            if (mage != null && Vector3.Distance(transform.position, mage.gameObject.transform.position) > 5f)
            {
                man.SetDestination(target.position);
                transform.GetComponent<Animation>().Play("run");//播放角色行走動畫 
              
                //啟用血條指令碼
                gameObject.GetComponent<npc>().enabled = true;
                mage.gameObject.GetComponent<jianke>().enabled = true;
                //() transform.LookAt(mage.transform);沒意義
                yield return StartCoroutine(AIFollowHero());



            }
           
                
            
          
             

        


        }
    }
    IEnumerator AIFollowHero()
    {

        while (true)
        {
            /* if (mage != null)
              {
                  transform.LookAt(mage.transform);
                  transform.GetComponent<Animation>().Play("run");//播放角色跑動畫 
                  Vector3 dir = mage.transform.position - transform.position;

                  transform.Translate(dir.normalized * Time.deltaTime * speed * 0.8f, Space.World);
              }

                */
            transform.GetComponent<Animation>().Play("run");
            if (mage != null && Vector3.Distance(transform.position, mage.gameObject.transform.position) <= 1.5f)
            {


              
               // transform.LookAt(mage.transform);
                man.isStopped = true;
                transform.GetComponent<Animation>().Play("attack");
                qiang.GetComponent<MeshCollider>().enabled = true;
                i = 1;
                yield return new WaitForSeconds(2f);


            }
            else if (mage != null && Vector3.Distance(transform.position, mage.gameObject.transform.position) > 1.5f)
            {

                //transform.LookAt(mage.transform);
                // transform.GetComponent<Animation>().Play("run");//播放角色跑動畫 
                 man.isStopped=false;
                man.SetDestination(target.position);
               
            }
          

            transform.LookAt(mage.transform);
           yield return new WaitForEndOfFrame();

        }
    }

直接說第二個協程,這裡其實是一個距離判斷,到了主角身邊時要停止尋路,不然會一直撞上主角,因為它其實一直想走到主角腳下踩得位置,從而很違和,當主角遠離它時,要把停止關閉,並重新設定主角當前位置為目標點,不然小兵不會重新整理目標位置。

這裡的man.isStopped是某個版本之後更改的API,之前應該是man.Stop();關閉,man.Resume();開啟。當然,還存在著很多例如清除當前路徑等等函式,這個對應自己需求去查API即可,網上還有很多教程,尋路的時候還可以實現MOBA遊戲那樣三路小兵各自走不同路線等等方案。