Unity实用功能之实用Navigation(自动寻路系统)制作简易AI巡逻

2,354 阅读3分钟

这是我参与8月更文挑战的第11天,活动详情查看:8月更文挑战

概述

AI巡逻功能一般在游戏开发中使用的比较多,最近做了一个打僵尸的项目,僵尸生成后要在城市中随机游走,当有玩家打僵尸的时候,僵尸会跑到玩家身前攻击玩家。这里就涉及到了AI的巡逻功能,所以就自己研究了一下。本片文章就简单的介绍一下实现过程

思路分析

我这里使用的是Unity自带的寻路系统Navigation,整体思路就是,初始给AI一个目标点,让AI向着目标点移动,当AI走至目标点之后,再次以AI为中心,在半径为10-15米范围内随机取再取一个目标点让AI继续朝着目标点前进,直到有玩家攻击僵尸为止。

功能实现

场景搭建

首先我们在Unity中搭建一个简易的场景,一个地形,N多个Cube当障碍物,然后在放入AI资源(网上寻找就行,用方块代替也都行)。 最终场景如下

image.png 半透明方块为障碍物,红球是为了看其中一个僵尸的目标点。

Nav Mesh Agent组件

Nav Mesh Agent组件可以实现对指定对象寻路的代理,该组件自带了许多参数,可以通过修改Nav Mesh Agent组件的参数来实现对代理器大小,速度,加速度的控制,这里面就不做过多的讲解,只介绍一下参数。

image.png

  • Speed:移动速度
  • Angular Speed:角速度
  • Acceleration:加速度
  • Stopping Distance:到达时与目的地的路线
  • Auto Braking:是否自动停止无法到达目的地的路线
  • Radius:半径
  • Height:高度
  • Quality:障碍物躲避质量
  • Priority:回避优先等级
  • Auto Traverse Off Mesh Link:是否自动移动Off Mesh Link
  • Auto Repath:原有路径发现变化时是否重新寻路
  • Area Mask:在寻路径是将考虑的区域类型

计算目标点开始寻路

首先我们先随机取一个方向,作为下一个目标点的方向

//随机取一个方向
Vector3 dir = new Vector3(Random.Range(-10f, 10f), 0, Random.Range(-10f, 10f)).normalized;

接下来,在这个方向的基础上随机取一个目标点,minDis为最小距离, maxDis为最大距离

//在这个方向的基础上取一个目标点
Vector3 pos = transform.position + transform.rotation * dir * Random.Range(minDis, maxDis);

设置AI的目标点,并让目标进行移动。首先需要先获取AI身上的NavMeshAgent组件,然后通过方法SetDestination设置目标点即可

public NavMeshAgent NavMesh;
NavMesh = this.gameObject.GetComponent<NavMeshAgent>();
NavMesh.SetDestination(pos);

image.png 这样AI就可以像目标点移动了。
接下来要判断AI是否到达目标点。此方法即使目标点在一些不可能到达的目的地也可以计算

 /// <summary>
 /// 判断是否到达目目标点
 /// </summary>
 /// <returns>true为未到达,false到达</returns>
 public bool IsMoving()
 {
     if (!aidata.NavMesh.enabled)
         return false;
     bool r = aidata.NavMesh.pathPending ||
     aidata.NavMesh.remainingDistance > aidata.NavMesh.stoppingDistance ||
     idata.NavMesh.velocity != Vector3.zero;
     r = aidata.NavMesh.enabled ? r : false;
     return r;
 }

然后我们在Update中实时判断是否到达,到达之后再次进行目标点获取与设置

if (!IsMoving())
{
    //获取新目标点
    //设置AI新的目标点           
}

最终结果如下:

454545.gif

写在最后

所有分享的内容均为作者在日常开发过程中使用过的各种小功能点,分享出来也变相的回顾一下,如有写的不好的地方还请多多指教。Demo源码会在之后整理好之后分享给大家。欢迎大家相互学习进步。