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组件会在挂载的物体运动结束后重新烘焙路线。
如有问题,欢迎留言讨论(๑•̀ㅂ•́)و✧