unity NavMeshAgent(自动寻路)+鼠标点击到达地点+动态障碍寻路

Unity NavMeshAgent(自动寻路)+鼠标点击到达地点+动态障碍寻路

1、利用NavMeshAgent实现简单寻路(无需手动操作,设置好目标即可寻路)
效果:
在这里插入图片描述
步骤
(1)先创建地形及障碍物(长方体),障碍物一定要放到plane层级下方。
在这里插入图片描述
(2)点击Plane,在右侧检查器中,点击“静态的”,勾选“Navigation Static”,并应用到子物体
在这里插入图片描述
(3)点击“窗口”,选择“AI”,点击其中的“导航(Navigation)”
在这里插入图片描述
(4)点击后打开了导航界面,首先,点击“对象”
点击层级视图中的Plane,将Plane设置为"Walkable"
在这里插入图片描述
点击Plane下的障碍物,将其都设置为“Not Walkable”
在这里插入图片描述
然后选择“烘焙”区域,根据自身可调整参数,然后点击Bake.
在这里插入图片描述
烘焙中主要是地形对寻路的影响:
●代理半径(Agent Radius)可理解为寻路者的半径
●代理高度(Agent Height) 可理解为寻路者的高度
●最大坡度(Max Slope) 超过这个坡度寻路者则无法通过。
●步高(Step Height) 是楼梯的最大高度,超过这个高度寻路者则无法通过。
●掉落高度(DropHeight) 寻路者可以跳落的高度极限。
●跳跃距离(Jump Distance)寻路者的跳跃距离极限。

点击Bake后,会在Scenes中自动生成文件夹及文件
在这里插入图片描述
此时观察场景中,其中蓝色部分就是可以移动的部分。
在这里插入图片描述
(5)添加Play(寻路者)和Target(寻路目标)
在这里插入图片描述
点击Play,在检查器为其添加“Nav Mesh Agent”组件
在这里插入图片描述
创建一个脚本“Move.cs”,挂载到Play上,代码如下

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

public class Move : MonoBehaviour
{
    
    
    //play位置
    private Transform play_Pos;
    //目标位置
    private Transform target_Pos;
    //自动寻路组件
    private NavMeshAgent play_agent;
    void Start()
    {
    
    
        play_Pos = this.transform;
        target_Pos = GameObject.Find("Target").GetComponent<Transform>();//一定是寻路目标的名字
        play_agent = GetComponent<NavMeshAgent>();
    }
     private void Update()
    {
    
    
         play_agent.SetDestination(target_Pos.position);
     }
}

(6)保存,返回unity运行即可。
PS:
注意,在Play物体上添加的Nav Mesh Agent组件,其中的属性可以改变物体的移动速度,但在改变速度时同时也要改变角速度,这样物体的运动路线才是正确的。如果速度过大而没改变角速度就会出现物体路线绕远或绕圈的现象。(参考:默认速度3.5,角速度120,可以根据默认比例来改变速度和角度)
在这里插入图片描述

2、鼠标点击到达指定地点
效果:
在这里插入图片描述
(1)前面操作和上面一样,只是不用设置Target物体,因为这里的Target是鼠标点击的位置。
在这里插入图片描述
(2)新建一个脚本ButtonMove.cs ,来替代上面的Move.cs挂载到Play上。
代码如下

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

public class ButtonMove : MonoBehaviour
{
    
    
    private NavMeshAgent play_Agent;

    private Transform play_Pos;

    private Vector3 mousePositionOnScreen;

    private Vector3 screenPosition;
    private Vector3 mousePositionInWorld;
    // Start is called before the first frame update
    void Start()
    {
    
    
        play_Agent = GetComponent<NavMeshAgent>();
    }

    // Update is called once per frame
    void Update()
    {
    
    
        if (Input.GetMouseButton(0))
        {
    
    
            play_Pos=this.transform;
           //Debug.Log(Input.mousePosition); 
          //获取游戏对象在世界坐标中的位置,并转换为屏幕坐标;
           screenPosition = Camera.main.WorldToScreenPoint(play_Pos.position);
          //获取鼠标在场景中坐标
           mousePositionOnScreen = Input.mousePosition;
          //让鼠标Z坐标=场景中Play坐标
           mousePositionOnScreen.z = screenPosition.z;
          //将鼠标的屏幕坐标转化为世界坐标
           mousePositionInWorld = Camera.main.ScreenToWorldPoint(mousePositionOnScreen);
          //设置目标点
           play_Agent.SetDestination(mousePositionInWorld);
        }
    }
}

3、动态障碍物(该障碍物在场景运行后会运动,导致在运行前烘焙的路线不可用)
效果:
在这里插入图片描述
(1)搭建场景,创建一个运行后会动的障碍物,在这里我为这个障碍物创建了一个动画,运行后,障碍物后立起来。
运行前:
在这里插入图片描述
运行后:
在这里插入图片描述
(2)其他操作和之前的简单寻路操作相同。
不同之处就是,要将会动的障碍物的检视视图处的Navigation static取消勾选,勾选“Nothing”
在这里插入图片描述
取消勾选后,再去导航界面(Navigation)界面烘焙一下。
然后点击“会动的障碍物”,为其添加组件“Nav Mesh Obstacle”
在这里插入图片描述
这个“会动的障碍物”在处于关闭的时候会变为无法通过的状态了.
Nav Mesh Obstacle组件会在挂载的物体运动结束后重新烘焙路线。

如有问题,欢迎留言讨论(๑•̀ㅂ•́)و✧

猜你喜欢

转载自blog.csdn.net/weixin_51565051/article/details/130445067