[Unity3D]AI智能寻路精讲/敌人自动避障寻路

在很多游戏中,敌人经常要在复杂的地形中追着主角跑,因为场景中存在很多障碍物,所以敌人的AI要足够聪明,才能找出到达目标点的最近道路,且绕开障碍物。写一个完善的寻路算法是比较有挑战性的,特别是在复杂的3D场景中,好在Unity提供了一个非常实用的寻路功能,只需要较少的代码即可实现复杂的寻路功能。

下面我将给大家介绍如何去具体实现这个功能:

Unity的寻路系统分为两部分: (1)一部分是对场景进行设置, 使其满足寻路算法的需求; (2)设置寻路者。

1. 步骤一

选择除敌人和Player以外的所有场景模型,然后单击Inspcetor窗口Static 旁边的小三角形按钮显示出下拉列表,确认[Navigton Satic]被选中,Unity 将指导这样的模型用于寻路计算,如图1-1所示。

unity3D AI寻路 unity3d寻路系统_寻路

[图1-1] 注:Cube(3)在这里面是敌人模型,所以没有选上2.步骤二

在菜单栏中选择[ Window] -> [Navigation],打开Navigation窗口,如图2-1所示。

unity3D AI寻路 unity3d寻路系统_unity_02

[图2-1] 注:在这里我们可以看见整个地形,除了障碍都被覆盖上了颜色,这里就是Unity帮我们计算地形上的障碍,来指导敌人模型用来自动寻路,如果场景里存在有没有勾选[Navigton Satic]的模型,即使它在场景里面,Unity也会默认他不在场景中来对人物进行自动寻路,下面画两张图给大家解释:1.场景里面所有场景模型都勾选了[Navigton Satic],敌人将按照Unity对勾选[Navigton Satic]的场景模型进行计算,寻找最短路线:

unity3D AI寻路 unity3d寻路系统_unity_03

2.场景里面有部分模型没有勾选[Navigton Satic],Unity就会默认这个位置不会存在场景模型,然后按照不存在这个模型来计算最短距离,(蓝色部分的场景模型就是没有勾选[[Navigton Satic],Unity在计算最短路线时就会默认他们不存在):

unity3D AI寻路 unity3d寻路系统_unity3D AI寻路_04

这也就解释了为什么有的同学在更新一下场景模型后,AI自动寻路就不灵了,出现了卡墙等情况,原因大多是更新场景后没有对场景进行重新烘焙,所以在每次更新场景后都要重新做一下步骤一和步骤二,不然就会出现上述情况打开Navigation窗口后,在Navigation面板下找到Bake,其面板如下:

unity3D AI寻路 unity3d寻路系统_unity_05

Bake窗口主要是定义地形对寻路的影响:

●Agent Radius和Height可以理解为寻路者的半径和高度。

●Max Slope是最大坡度,超过这个坡度寻路者则无法通过。

●Step Height是楼梯的最大高度,超过这个高度寻路者则无法通过。

●DropHeight表示寻路者可以跳落的高度极限。

●Jump Distance表示寻路者的跳跃距离极限。

大家可以根据自己的需求进行适当修改

3.步骤三 在Navigation窗口中设置好选项后,单击[Bake]按钮对地形进行计算(如果场景比较多,那计算的时间会稍微长一点,进度可以看右下角的进度条,待烘焙完成后再进行下一步操作),单击[Clear]按钮会清除计算结果。Bake出来的寻路数据,会被保存为一个文件,名为NavMesh.asset,当前关卡相关联,这一点与Lightmap很像。

接下来设置寻路者,也就是游戏中的敌人

4.步骤四

将自己准备好的敌人模型拖入场景中

unity3D AI寻路 unity3d寻路系统_游戏_06

为了方便我直接用的一个长方形作为了敌人,并给他添加了血条5.步骤五

在菜单栏中选择[Component]一[Nav Mesh Agent],将寻路组件指定给敌人。然后在Inspector窗口中进行进一步的设置, Speed 是最大运动速度,Angular Speed 是最大旋转速度,如图[5-1]所示。在Agent Type中选择[Open Agent Settings], 可以打Navigation的Agents窗口,设置Radius和Height,表示寻路者的半径和高度,如图[5-2]所示。

unity3D AI寻路 unity3d寻路系统_寻路_07

[图5-1]

unity3D AI寻路 unity3d寻路系统_c#_08

[图5-2]

6.步骤六 创建脚本AI.cs,添加代码如下:

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

public class AI : MonoBehaviour
{
private Transform target;   //设置追踪目标的位置
    public float MoveSpeed=2.5f; //敌人移动速度
    private NavMeshAgent navMeshAgent;  //设置寻路组件

    void Start()
    {
        target = GameObject.FindWithTag("Player").transform;  //获取游戏中主角的位置,在我的工程里面主角的标签是Player
        navMeshAgent = GetComponent<NavMeshAgent>();
        navMeshAgent.speed = MoveSpeed;  //设置寻路器的行走速度
        if (navMeshAgent == null) 
        {
            navMeshAgent = gameObject.AddComponent<NavMeshAgent>();
        }
    }


    void Update()
    {
        navMeshAgent.SetDestination(target.transform.position); //设置寻路目标
    }
}

这是敌人的脚本。在Sart函数中获得NaMesAgen组件,然后调用SeDestination函数设置一个目标点,即可自动追击主角。如果希望自行控制移动,可以使用CalculatePath函数计算出路径,然后按路径节点移动。我找了一篇博客作为参考:

CalculatePath函数计算出路径来进行寻路的链接参考

在这里我就不作过多说明了,想详细了解的同学可以自己去查一下。

在运行之前查看主角的标签是否为Player,如果不是就要进行更改:

unity3D AI寻路 unity3d寻路系统_c#_09

7.步骤七

将脚本AI.cs给指定敌人,运行游戏,敌人会找出最短路径向主角位置前进:

unity3D AI寻路 unity3d寻路系统_游戏_10