利用 NavMesh.CalculatePath寫出更加好的AI移動效果

感謝這位兄臺,雖然是亂點點出來的一個論壇,哈哈哈哈
這裏寫圖片描述

既然有具體的想法和步驟了,那我們就來完善一下吧,實現一個demo。

新建一個場景,添加plane,隨便添幾個cube,做2個橋的樣子。選擇橋和plane在Navigation上面點擊Navigation Static。然後bake一下,生成導航地圖。如下
這裏寫圖片描述

添加自己的人物或怪物模型,這裏就不詳細介紹了(怪物的animator controller,只有一個idle和移動的融合樹)如圖
這裏寫圖片描述
這裏寫圖片描述
比較簡單的移動融合樹,不會的話,怕是你動畫系統沒學好額。

可以看出來,控制移動的有2個參數,一個是Direction方向,和Speed速度。

這裏爲了速度瞭解效果,我們自己來控制速度,方向就由自動尋路來控制。

代碼如下:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.AI;

public class AIDragon : MonoBehaviour
{
    public GameObject instance;
    public GameObject target;
    private NavMeshAgent agent;
    private NavMeshPath path;
    private Animator animator;
    private float dis;
    private float RunSpeed = 1;
    void Start ()
    {
        animator = GetComponent<Animator>();
        path = new NavMeshPath();
        dis = GetComponent<CapsuleCollider>().radius*2;
        //創建路徑
        NavMesh.CalculatePath(transform.position, target.transform.position, NavMesh.AllAreas, path);
        NavMeshHit hit;
        //改變路徑中每個點的位置,爲了不貼邊緣走,這樣很怪。
        for (int i = 1; i < path.corners.Length - 2; i++)
        {
            bool result = NavMesh.FindClosestEdge(path.corners[i], out hit, NavMesh.AllAreas);
            if (result && hit.distance < dis)
                path.corners[i] = hit.position + hit.normal* dis;
        }
        Mydebug();
    }

    private float Speed;
    private float Direction;
    private int k = 1;
    void Update ()
    {
        Speed = Input.GetAxis("Vertical");
       // Direction = Input.GetAxis("Horizontal");
        // Debug.Log(Speed);
        // Debug.Log(Direction);
        if (Input.GetMouseButton(1))
        {
            RunSpeed = Mathf.MoveTowards(RunSpeed, 2f, Time.deltaTime);
        }
        else
        {
            RunSpeed = Mathf.MoveTowards(RunSpeed, 1f, Time.deltaTime);
        }
        if (Vector3.Distance(transform.position, path.corners[k]) <= RunSpeed&&k<path.corners.Length-1)
        {
            k++;
        }
        if(k<path.corners.Length)
        LookRightDirection(path.corners[k]);
        animator.SetFloat("Speed",Speed* RunSpeed);
        animator.SetFloat("Direction",Direction);


    }


    //用於實時改變方向
    public void LookRightDirection(Vector3 tr)
    {
        Vector3 relative   = transform.InverseTransformPoint(new Vector3(tr.x,0,tr.z));
        float angle   = Mathf.Atan2(relative.x, relative.z) * Mathf.Rad2Deg;
        Direction = angle/180f*RunSpeed*1.2f;
        if (Mathf.Abs(Direction) > 1)
        {
            Direction = Mathf.RoundToInt(Direction);
            Debug.Log(Direction);
        }
    }


    public void Mydebug()
    {
        Debug.Log(path.corners.Length);
        for (int i = 0; i < path.corners.Length; i++)
        {
            GameObject.Instantiate(instance, path.corners[i], Quaternion.identity);
        }
      // Debug.Log(path.corners.Length);

    }

}

地圖bake的時候邊角儘量去掉,不然有可能人物被物理系統阻擋住。
這裏寫圖片描述

這裏寫圖片描述
這裏寫圖片描述

我們只控制了速度,物體完全是自己尋找目標。

去優化代碼把,讓遊戲更好玩,嘿嘿。

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