当前位置: 首页 > article >正文

Unity3D学习FPS游戏(11)敌人AI巡逻(NavMesh)

前言:前面两篇博客已经实现了简单的敌人,但是呢,这样很无趣。因为敌人只会站在原地被攻击,所以本篇我们将实现敌人AI巡逻,让敌人动起来。

敌人AI巡逻

  • 场景丰富一下
  • 导航网格NavMesh
    • 构建导航网格
    • 导航网格优化
      • 玩家被当作障碍物
      • 不允许爬窗
    • 敌人添加Nav Mesh Agent
  • 巡逻功能
    • 目标
    • 设置巡逻点
    • 代码控制敌人巡逻
  • 效果

场景丰富一下

之前的场景只有一个地面,因为要让敌人巡逻,而敌人巡逻位置通常一个小范围的地方。
所以我从素材里面拖出了一个房子,打算让AI只在房子里面巡逻。
把房子的屋顶删掉了,方便观察AI移动情况。
大家可以根据自己需求去构建场景。
在这里插入图片描述

导航网格NavMesh

这是Unity自带的一个可以实现自动寻路的AI功能,我们将用它实现敌人AI巡逻,以及后续的追击玩家等寻路功能。

构建导航网格

创建NavMesh Surface组件,菜单-GameObject-AI-NavMesh Surface,然后直接烘焙Bake就好了。
在这里插入图片描述
NavMesh Surface是一个导航网格,能够让我们为敌人AI定义可以行走的表面。

导航网格优化

玩家被当作障碍物

构建网格时候,会发现,玩家也会被当成障碍物。
在这里插入图片描述
可以通过图层来进行烘培时忽略玩家。
点击Player的属性,找到图层Layer,添加新的Layer。
在这里插入图片描述
在这里插入图片描述
然后把新建的Layer,给Player属性中换上。

这时候再回到我们的NavMesh中,把Include Layers中的Player给勾选掉重新烘培,就不会把玩家视作为障碍物了。
在这里插入图片描述

不允许爬窗

会发现自动创建的导航网格,爬窗也有路径。
在这里插入图片描述
可以在Agent Type进行修改。
在这里插入图片描述
可以设置Agent代理的一些属性,会决定导航网格的构建。目前默认的是普通人类的角色设置,我们可以加号新建一个设置为HoverBot。
Radius表示能通过的最小宽度;Height表示能通过的最小高度;Step Height设置物体向上能到达的路径的高度(类似人一步能迈多高),例如上楼和上坡等带有向上走的行为;Max Slope设置场景的斜坡的最大角度;
然后因为不想让它能翻窗所以,Step Height要非常低,还有Max Slope也要低些。
在这里插入图片描述
修改NavMeshSurface的Agent Type为HoverBot,重新烘培。
在这里插入图片描述
这时候烘焙出来就不会有翻窗和把玩家当作障碍物的问题了。

敌人添加Nav Mesh Agent

导航网格构建好了,还需要让敌人挂载Nav Mesh Agent组件,才能控制敌人在NavMesh上移动。
记得设置Agent Type切换为HoverBot。
在这里插入图片描述
通过代码控制敌人的NavMeshAgent能够自动找到去目标地点的最短路,并移动过去。

巡逻功能

目标

希望敌人在小屋子范围里面巡逻走动。

设置巡逻点

创建WayPoints空的GameObject,房间内巡逻就是在四个点之间循环移动,所以在WayPoints下面创建四个GameObject调整Transform,这四个位置点就作为巡逻点。
在这里插入图片描述

代码控制敌人巡逻

主要是操作NavMeshAgent来控制,常用的几个属性有:

  • destination是NavMeshAgent组件的目的地
  • nextPosition是NavMeshAgent组件的当前的位置信息
  • pathPending判断路径是否在计算路径
  • remainingDistance和目标距离的剩余位置

思路主要是,获取前面设置的四个位置,以此按照顺序到达不同巡逻点。每次到达一个巡逻点后,就前往下一个巡逻点。

代码思路,可以看具体的代码和注释会理解的清楚。主要就是Update的时候判断是否抵达当前巡逻点,抵达了就去下一个巡逻点。

[Header("AI")]
public NavMeshAgent enemyAgent;// 路径导航代理
public GameObject wayPointParent;// 存放巡逻点
public Transform[] wayPoints;// 存放巡逻点数组
public int wayPointIndex = 1;// 当前巡逻点数组下标
void Start()
{
    enemyAgent = this.GetComponent<NavMeshAgent>();// 获取NavMeshAgent组件
    if (wayPointParent)// 获取四个巡逻点存放在数组中
    {
        wayPoints = wayPointParent.GetComponentsInChildren<Transform>();
        SetNextDestination();// 设置下一个目标位置
    }
}
void Update()
{
    // 没有在计算路径,而且到达目标位置很近(距离小于0.1f)
    if (!enemyAgent.pathPending&&enemyAgent.remainingDistance<0.1f)
    {
        SetNextDestination();// 设置下一个目标位置
    }
}
// 设置下一个目标位置
private void SetNextDestination()
{
    if (wayPoints.Length <= 0) // 不存在巡逻点,就不用设置了
        return;
    enemyAgent.destination = wayPoints[wayPointIndex].position;// 设置下一个目标位置
    wayPointIndex++;// 下标加加
    if (wayPointIndex == wayPoints.Length)// 巡逻点下表循环
        wayPointIndex = 1;// 跳过第0个巡逻点,因为获取的第0个巡逻点是Parent,用不上
}

效果

在这里插入图片描述


http://www.kler.cn/a/392166.html

相关文章:

  • 深入理解接口测试:实用指南与最佳实践5.0(三)
  • 基于混合配准策略的多模态医学图像配准方法研究
  • 2411C++,C++26反射示例
  • 多叉树笔记
  • Linux设置Nginx开机启动
  • 科技云报到:数字化转型,从不确定性到确定性的关键路径
  • C++多态及其在设计模式中的作用举例
  • 【webrtc】 RTP 中的 MID(Media Stream Identifier)
  • Spring Boot编程训练系统:构建企业级应用
  • 基于BILSTM及其他RNN序列模型的人名分类器
  • 革新农业未来!Dimitra生态币价双双腾飞在即
  • AI 大模型在软件开发中的角色
  • IntelliJ IDEA 启动报 Unsupported Java Version
  • HTTP 客户端怎么向 Spring Cloud Sleuth 传输跟踪 ID
  • 彻底理解ARXML中的PDU
  • 我们的第2个原创项目上线啦
  • ubuntu20.04 解决Pytorch默认安装CPU版本的问题
  • 生成S19(SRecord)的数据段Hash/AES/RSA
  • python练习-Django web入门
  • 【计算机网络】设备网卡NIC的工作内容有哪些呢?
  • python+pptx:(三)添加统计图、删除指定页
  • rust构建web服务器
  • Linux终端命令后台运行
  • spring中r类是什么
  • ubuntu下的一些常用指令
  • 如何从头开始构建神经网络?(附教程)