Unity自学之旅05
Unity自学之旅05
- Unity学习之旅⑤
- 📝 AI基础与敌人行为
- 🥊 AI导航
- 理论知识(基础)
- 开始实践
- 🎃 敌人游戏机制
- 追踪玩家
- 攻击玩家
- 子弹碰撞
- 完善游戏失败条件
- 🤗 总结归纳
Unity学习之旅⑤
📝 AI基础与敌人行为
🥊 AI导航
理论知识(基础)
一、导航系统的基本组件
- NavMesh(导航网格):
- NavMesh 是 Unity 中 AI 导航的基础,它是一个表示可行走区域的网格。它将场景中的可行走表面(如地面、楼梯等)进行三角剖分,形成一个平面的网格,用于代理(Agent)导航。
- 生成 NavMesh 的步骤:
- 首先,需要将场景中的几何体标记为静态(Static),以便 Unity 可以将它们纳入 NavMesh 的计算。
- 然后,打开 Navigation 窗口(Window -> AI -> Navigation),在 Bake 选项卡中调整设置,例如 Agent Radius(代理半径)、Agent Height(代理高度)等,这些设置决定了代理在场景中占用的空间大小和形状。
- 点击 Bake 按钮,Unity 会生成 NavMesh,显示为场景中的蓝色网格。
- NavMeshAgent(导航网格代理):
- 这是附加在游戏对象上的组件,用于让对象在 NavMesh 上移动。
- 主要属性:
- Speed:代理的移动速度。
- Acceleration:代理的加速度。
- Stopping Distance:距离目标多远时停止移动。
- Radius:代理的半径,用于避障和计算可行走区域。
- Height:代理的高度,决定了代理可以通过的最小空间高度。
- NavMeshObstacle(导航网格障碍物):
- 该组件用于表示场景中的动态障碍物。当一个对象附加了
NavMeshObstacle
时,它会影响NavMeshAgent
的导航路径。 - 可以设置为
Carve
模式,这会在 NavMesh 上动态地修改 NavMesh,使代理能够绕开障碍物。
- 该组件用于表示场景中的动态障碍物。当一个对象附加了
二、导航行为和逻辑
- 路径规划:
NavMeshAgent
会自动根据 NavMesh 为代理规划从当前位置到目标位置的最短路径。它会考虑障碍物和可行走区域。- 可以使用
agent.remainingDistance
来检查代理离目标的剩余距离,使用agent.pathStatus
来查看路径的状态,如是否完成、正在计算或被阻塞。
- 避障:
- Unity 的导航系统会自动处理代理之间和代理与障碍物之间的避障。通过设置
NavMeshAgent
的属性,如Radius
和Avoidance Priority
,可以调整避障行为。 - 代理之间会根据彼此的
Avoidance Priority
进行避障,较低优先级的代理会主动避让较高优先级的代理。
- Unity 的导航系统会自动处理代理之间和代理与障碍物之间的避障。通过设置
- 动态导航:
- 当场景中的障碍物或目标位置发生变化时,
NavMeshAgent
会自动重新计算路径。 - 例如,如果要在游戏运行时改变目标位置,可以调用
agent.SetDestination(newDestination);
,其中newDestination
是一个Vector3
类型的新位置。
- 当场景中的障碍物或目标位置发生变化时,
开始实践
window→package manager 选择 Unity Registry 然后搜索 AI Navigation
window→ai→navigation(obsolete) ,这里是因为我所使用的Unity版本那个AI Navigation static 已经弃用了,我更改了一种使用方式。
选择Environment,然后为点击Inspector中的Static,接着将Environment的对象及其子对象都设置为Navigation Static.
点击Bake→bake
为Enemy添加NavMeshAgent,让敌人可以在NavMesh上面行走。
绘制几个路径点,用于敌人的自动巡逻。
引用巡逻点,编辑EnemyBehavior脚本
// 巡逻点的transformpublic Transform PatrolRoute;// 四个巡逻点的transform集合public List<Transform> Locations;void Start(){// 脚本运行时,初始化巡逻路径InitializePatrolRoute();}void InitializePatrolRoute(){foreach (Transform t in PatrolRoute){Locations.Add(t);}}
让Enemy跟着巡逻点动起来,在此编辑脚本
// ...
// 默认第一个索引为0,即先走第一个巡逻点
private int _locationIndex = 0;// NavMeshAgent的引用
private NavMeshAgent _agent;void Start()
{// 获取Enemy对象上的NavMeshAgent组件的引用_agent = GetComponent<NavMeshAgent>(); // 脚本运行时,初始化巡逻路径InitializePatrolRoute(); MoveToNextPatrolLocation();
}// 移动到下一个巡逻点
void MoveToNextPatrolLocation()
{_agent.destination = Locations[_locationIndex].position;
}
//....
现在只会移动到第一个巡逻点,然后我们的目的是,在每个巡逻点,循环往复的进行移动,这个时候就需要在Update()中搞点事情了。
void Update()
{// 检测当前对象与目标位置距离if(_agent.remainingDistance < 0.2f && !_agent.pathPending){MoveToNextPatrolLocation();}
}// 移动到下一个巡逻点void MoveToNextPatrolLocation(){if(Locations.Count == 0) return;_agent.destination = Locations[_locationIndex].position;// 索引循环往复_locationIndex = (_locationIndex + 1) % Locations.Count; }
🎃 敌人游戏机制
敌人按照巡逻路线进行巡逻,当与玩家碰撞后,减少玩家生命值,然后敌人回到初始位置,玩家也可以攻击敌人,减少其生命值。
追踪玩家
当玩家进入敌人警戒范围时,敌人会直接奔向玩家。
// 玩家的Transform引用public Transform Player;void Start(){// ...// 获取Player对象的引用Player = GameObject.Find("Player").transform;}// ...// 碰撞触发器void OnTriggerEnter(Collider other){if(other.name == "Player"){// 玩家进入到警戒范围后,敌人奔向玩家_agent.destination = Player.position;Debug.Log("玩家进入警戒范围");} }
攻击玩家
攻击玩家的逻辑很简单,当玩家与敌人发生碰撞时,玩家减少生命值,并且在GUI上显示
修改玩家的Playerbehavior脚本(敌人脚本也可以,因为碰撞是相互的)
// gameManager的引用,因为HP,收集道具数量都在该处存放
private GameBehavior _gameManager;void Start(){// 将当前player的刚体组件获取并设置_rb = GetComponent<Rigidbody>();// 获取当前角色的胶囊碰撞体_col = GetComponent<CapsuleCollider>();_gameManager = GameObject.Find("Game_Manager").GetComponent<GameBehavior>();}// 发生碰撞时void OnCollisionEnter(Collision collision){// 如果与敌人碰撞则HP-1if (collision.gameObject.name == "Enemy"){_gameManager.HP -= 1;}}
这里的话需要注意一个问题,就是敌人身上的碰撞体为碰撞触发器,勾选了Is Trigger,然后直接通过Player的OnCollisionEnter()并不会触发,需要给敌人再加入一个碰撞体就可以了。
子弹碰撞
为Player添加反击手段,逻辑就是敌人有三滴血,当子弹射击三次并且击中敌人后,敌人自动销毁。
编辑敌人Enemy的游戏脚本
// 敌人的HP=3
private int _lives = 3;
public int EnemyLives
{get { return _lives; }set{_lives = value;if (_lives <= 0){Destroy(this.gameObject);Debug.Log("敌人死亡");}}
}void OnCollisionEnter(Collision collision)
{// 当子弹碰撞到敌人时if(collision.gameObject.name == "Bullet(Clone)"){EnemyLives -= 1;Debug.Log("遭受子弹射击");}
}
完善游戏失败条件
逻辑是,生命值为0时,游戏暂停,出现一个按钮说:你输了。
先绘制一个Button按钮,和之前的一样,默认禁用即可,当生命值为0时,在脚本内调用。
编辑GameManager的脚本
public Button LossButton;
private int _playerHp = 10;
public int HP
{get { return _playerHp; }set{//...if (_playerHp <= 0){ProgressText.text = "You want another life with that?";LossButton.gameObject.SetActive(true);Time.timeScale = 0f;}else{ProgressText.text = "Ouch... that's got hurt.";}Debug.LogFormat("HP:{0}", _playerHp);}
}
🤗 总结归纳
本文主要介绍了在 Unity 中实现 AI 导航以及构建敌人游戏机制的方法。包括导航系统的基本组件、导航行为和逻辑,以及敌人的巡逻、追踪玩家、攻击玩家、被子弹击中和完善游戏失败条件等功能。
重要亮点
- 导航系统基本组件:Unity 中 AI 导航的基础是 NavMesh,它将场景中的可行走表面进行三角剖分形成网格。NavMeshAgent 是附加在游戏对象上用于在 NavMesh 上移动的组件,NavMeshObstacle 用于表示动态障碍物。
- 导航行为和逻辑:NavMeshAgent 能自动规划从当前位置到目标位置的最短路径,处理避障和动态导航。例如,当场景中的障碍物或目标位置变化时,会自动重新计算路径。
- 敌人巡逻机制:通过为敌人添加 NavMeshAgent,设置巡逻点,编写脚本实现敌人在巡逻点之间循环往复移动。
- 追踪玩家:当玩家进入敌人警戒范围时,敌人会奔向玩家。通过在敌人脚本中检测玩家进入碰撞触发器,设置敌人的目标位置为玩家位置。
- 攻击玩家:当玩家与敌人发生碰撞时,玩家减少生命值。在玩家脚本和敌人脚本中分别处理碰撞事件。
- 完善游戏失败条件:当玩家生命值为 0 时,游戏暂停,出现 “你输了” 按钮。在游戏管理器脚本中根据玩家生命值控制按钮的显示和游戏时间的暂停。
相关文章:

Unity自学之旅05
Unity自学之旅05 Unity学习之旅⑤📝 AI基础与敌人行为🥊 AI导航理论知识(基础)开始实践 🎃 敌人游戏机制追踪玩家攻击玩家子弹碰撞完善游戏失败条件 🤗 总结归纳 Unity学习之旅⑤ 📝 AI基础与敌…...
linux中关闭服务的开机自启动
引言 systemctl 是 Linux 系统中用于管理 systemd 服务的命令行工具。它可以用来启动、停止、重启服务,管理服务的开机自启动,以及查看服务的状态等。 什么是 systemd? systemd 是现代 Linux 发行版中默认的 初始化系统(init sys…...

Python----Python高级(文件操作open,os模块对于文件操作,shutil模块 )
一、文件处理 1.1、文件操作的重要性和应用场景 1.1.1、重要性 数据持久化: 文件是存储数据的一种非常基本且重要的方式。通过文件,我们可 以将程序运行时产生的数据永久保存下来,以便将来使用。 跨平台兼容性: 文件是一种通用…...
ubuntu黑屏问题解决
重启Ubuntu后,系统自动进入tty1,无法进入桌面。想到前几天安装了一些主题之类的,然后今天才重启,可能是这些主题造成冲突或者问题了把。 这里直接重新安装ubuntu-desktop解决: 更新源: sudo apt-get upd…...

Java如何实现反转义
Java如何实现反转义 前提 最近做的一个需求,是热搜词增加换一批的功能。功能做完自测后,交给了测试伙伴,但是测试第二天后就提了一个bug,出现了未知词 levis。第一眼看着像公司售卖的一个品牌-李维斯。然后再扒前人写的代码&…...

动态规划(路径问题)
62. 不同路径 62. 不同路径 - 力扣(LeetCode) 动态规划思想第一步:描述状态~ dp[i][j]:表示走到i,j位置时,一共有多少种方法~ 动态规划思想第二步:状态转移方程~ 动态规划思想第三步…...
python http调用视觉模型moondream
目录 一、什么是moondream 二、资源地址 三、封装了http进行接口请求 四、代码解析 解释 可能的改进 一、什么是moondream Moondream 是一个针对视觉生成任务的深度学习模型,专注于图像理解和生成,包括图像标注(captioning)、问题回答(Visual Question Answering,…...

Spark Streaming编程基础
文章目录 1. 流式词频统计1.1 Spark Streaming编程步骤1.2 流式词频统计项目1.2.1 创建项目1.2.2 添加项目依赖1.2.3 修改源目录1.2.4 添加scala-sdk库1.2.5 创建日志属性文件 1.3 创建词频统计对象1.4 利用nc发送数据1.5 启动应用,查看结果 2. 编程模型的基本概念3…...

深入 Flutter 和 Compose 的 PlatformView 实现对比,它们是如何接入平台控件
在上一篇《深入 Flutter 和 Compose 在 UI 渲染刷新时 Diff 实现对比》发布之后,收到了大佬的“催稿”,想了解下 Flutter 和 Compose 在 PlatformView 实现上的对比,恰好过去写过不少 Flutter 上对于 PlatformView 的实现,这次恰好…...

C# OpenCV机器视觉:红外体温检测
在一个骄阳似火的夏日,全球却被一场突如其来的疫情阴霾笼罩。阿强所在的小镇,平日里熙熙攘攘的街道变得冷冷清清,人们戴着口罩,行色匆匆,眼神中满是对病毒的恐惧。阿强作为镇上小有名气的科技达人,看着这一…...
FCA-FineDataLink认证
FCA-FineDataLink证书 Part.1:判断题 (总分:18分 得分:16) 第1题 判断题 数据同步只支持写入到已存在表,不支持自动建表(得分:2分 满分:2分) 正确答案:B 你的答案&…...
第19篇:python高级编程进阶:使用Flask进行Web开发
第19篇:python高级编程进阶:使用Flask进行Web开发 内容简介 在第18篇文章中,我们介绍了Web开发的基础知识,并使用Flask框架构建了一个简单的Web应用。本篇文章将深入探讨Flask的高级功能,涵盖模板引擎(Ji…...
js截取video视频某一帧为图片
1.代码如下 <template><div class"box"><div class"video-box"><video controls ref"videoRef" preload"true"src"https://qt-minio.ictshop.com.cn:9000/resource-management/2025/01/08/7b96ac9d957c45a…...

[云讷科技]Kerloud Falcon四旋翼飞车虚拟仿真空间发布
虚拟仿真环境作为一个独立的专有软件包提供给我们的客户,用于帮助用户在实际测试之前验证自身的代码,并通过在仿真引擎中添加新的场景来探索新的飞行驾驶功能。 环境要求 由于环境依赖关系,虚拟仿真只能运行在装有Ubuntu 18.04的Intel-64位…...

Jetson nano 安装 PCL 指南
本指南帮助 ARM64 架构的 Jetson Nano 安装 PCL(点云库)。 安装步骤 第一步:安装依赖 在终端中运行以下命令,安装 PCL 所需的依赖: sudo apt-get update sudo apt-get install git build-essential linux-libc-dev s…...

go-zero框架基本配置和错误码封装
文章目录 加载配置信息配置 env加载.env文件配置servicecontext 查询数据生成model文件执行查询操作 错误码封装配置拦截器错误码封装 接上一篇:《go-zero框架快速入门》 加载配置信息 配置 env 在项目根目录下新增 .env 文件,可以配置当前读取哪个环…...

Android中Service在新进程中的启动流程2
目录 1、Service在客户端的启动入口 2、Service启动在AMS的处理 3、Service在新进程中的启动 4、Service与AMS的关系再续 上一篇文章中我们了解了Service在新进程中启动的大致流程,同时认识了与客户端进程交互的接口IApplicationThread以及与AMS交互的接口IActi…...

论文速读|Matrix-SSL:Matrix Information Theory for Self-Supervised Learning.ICML24
论文地址:Matrix Information Theory for Self-Supervised Learning 代码地址:https://github.com/yifanzhang-pro/matrix-ssl bib引用: article{zhang2023matrix,title{Matrix Information Theory for Self-Supervised Learning},author{Zh…...
ubunut22.04安装docker(基于阿里云 Docker 镜像源安装 Docker)
安装 更新包管理器: sudo apt update 安装 Docker 的依赖包 sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release添加阿里云 Docker 镜像源 GPG 密钥: curl -fsSL https://mirrors.aliyun.com/docker-ce/linux/ubuntu/gp…...
k8s namespace绑定节点
k8s namespace绑定节点 1. apiserver 启用准入控制 PodNodeSelector2. namespace 添加注解 scheduler.alpha.kubernetes.io/node-selector3. label node 1. apiserver 启用准入控制 PodNodeSelector vim /etc/kubernetes/manifests/kube-apiserver.yaml spec:containers:- co…...

基于距离变化能量开销动态调整的WSN低功耗拓扑控制开销算法matlab仿真
目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.算法仿真参数 5.算法理论概述 6.参考文献 7.完整程序 1.程序功能描述 通过动态调整节点通信的能量开销,平衡网络负载,延长WSN生命周期。具体通过建立基于距离的能量消耗模型&am…...
Linux简单的操作
ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

React19源码系列之 事件插件系统
事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
关于uniapp展示PDF的解决方案
在 UniApp 的 H5 环境中使用 pdf-vue3 组件可以实现完整的 PDF 预览功能。以下是详细实现步骤和注意事项: 一、安装依赖 安装 pdf-vue3 和 PDF.js 核心库: npm install pdf-vue3 pdfjs-dist二、基本使用示例 <template><view class"con…...

spring Security对RBAC及其ABAC的支持使用
RBAC (基于角色的访问控制) RBAC (Role-Based Access Control) 是 Spring Security 中最常用的权限模型,它将权限分配给角色,再将角色分配给用户。 RBAC 核心实现 1. 数据库设计 users roles permissions ------- ------…...
MeanFlow:何凯明新作,单步去噪图像生成新SOTA
1.简介 这篇文章介绍了一种名为MeanFlow的新型生成模型框架,旨在通过单步生成过程高效地将先验分布转换为数据分布。文章的核心创新在于引入了平均速度的概念,这一概念的引入使得模型能够通过单次函数评估完成从先验分布到数据分布的转换,显…...

【RabbitMQ】- Channel和Delivery Tag机制
在 RabbitMQ 的消费者代码中,Channel 和 tag 参数的存在是为了实现消息确认机制(Acknowledgment)和精细化的消息控制。 Channel 参数 作用 Channel 是 AMQP 协议的核心操作接口,通过它可以直接与 RabbitMQ 交互: 手…...
stm32—ADC和DAC
ADC和DAC 在嵌入式系统中,微控制器经常需要与现实世界的模拟信号进行交互。STM32微控制器内置了模拟数字转换器(ADC)和数字模拟转换器(DAC),它们是实现这种交互的关键模块。 1. 模拟数字转换器(…...
Vue-github 用户搜索案例
一、前言 在 Vue 开发中,与后端或第三方 API 接口进行交互是非常常见的需求。GitHub 提供了开放的 RESTful API,非常适合用来练习 Vue 的异步请求和数据绑定功能。 本文将带你一步步实现一个完整的 GitHub 用户搜索系统,包括: …...