Unity——脚本与导航系统

Unity内置了一个比较完善的导航系统,一般称为Nav Mesh(导航网格),用它可以满足大多数游戏中角色自动导航的需求。


一、导航系统相关组件

Unity的导航系统由以下几个部分组成:

  1. Nav Mesh。Nav Mesh与具体的场景关联,它定义了场景中可以通过的三角面和非三角面的通路。Unity可以自动构建出Nav Mesh。
  2. Nav Mesh Agent。Nav Mesh Agent作为组件,要挂载到需要自动导航功能的角色上,它会为角色添加朝目标移动和避开障碍的功能。Nav Mesh Agent必须位于Nav Mesh之上才能发挥作用。
  3. Nav Mesh Obstacle。该组件将物体标记为障碍物,如阻碍角色行动的木桶或箱子。障碍物有两种起效的途径,一是动态障碍,让Nav Mesh Agent利用规避算法尽可能规避它;二是静态障碍,静态障碍会在Nav Mesh上挖洞,Nav Mesh Agent会围绕着这个洞修改寻路路径。如果障碍完全阻挡了路径,那么Nav Mesh Agent会去寻找一条新的路径。
  4. Off Mesh Link。某些某些通路用普通方法无法通过,但可能根据游戏设计是可以通过的。例如,一条阻断了Nav Mesh的水沟,在游戏中可以跳过去;从较低的平台无法走上较高平台,但可以通过梯子爬上去。导航系统允许在不连通的区域之间建立链接,这种链接关系通过Off Mesh Link进行标记

 解释静态、动态障碍的区别

在Unity中,静态障碍和动态障碍是指在导航系统中所采用的两种不同类型的障碍物,它们的区别主要体现在障碍物的移动性和对导航系统的影响。

1. 静态障碍(Static Obstacles):静态障碍物是指在游戏场景中位置不会发生改变的障碍物。它们通常是固定的环境元素,如墙壁、建筑物等。静态障碍物在导航系统的计算和路径规划中不会发生变化,只需要在初始化导航网格的时候标记出来即可。静态障碍物对导航系统的影响是恒定的,不会引起额外的计算开销

2. 动态障碍(Dynamic Obstacles):动态障碍物是指游戏场景中位置可能发生改变的障碍物。它们通常是动态的游戏角色、NPC、移动平台等。动态障碍物在导航系统中需要不断更新其位置信息,以便导航系统能够实时地针对它们进行路径规划。动态障碍物的移动会影响导航网格的可行走区域,导致导航系统需要重新计算路径。为了减少计算开销,Unity的导航系统提供了一些优化技术,如局部更新和动态避障等,以提高动态障碍物的移动效率和导航性能。

总结来说,静态障碍物是固定的,对导航系统没有实时的影响;而动态障碍物是可以移动的,对导航系统的计算和路径规划有实时的影响,需要特殊处理以保证角色可以正确避开它们。

二、构建导航网格 

 场景中的可移动区域一般包含了地形、平面、楼梯和斜坡等。要让导航系统自动处理这些地形,必须要事先在几何地形上搜集数据,预先计算参数,确定好导航面才可以。从几何关卡创建Nav Mesh的过程称为导航网格Bake。

 Unity有一个专门的Navigation窗口用于烘培操作,其基本的烘培操作只需以下两个步骤:

  1. 将所有场景中与导航有关的物体设置为Navigation Static。一般来说这些物体包含地形、平面、斜坡、楼梯、墙和静态障碍物,但不应包含运动的物体。选中物体后,单机Inspector右上角的小三角,打开菜单,可以看到Navigation Static选项。
  2. 打开Navigation窗口,选择主菜单的Window→AI→Navigation。然后打开其中的第三个标签页Bake,再单击下方的Bake按钮即可开始烘培。如果场景小,烘培会立即完成。烘培后可以看到但蓝色标记的可移动区域

 

有淡蓝色覆盖的部分就是可行走区域,而且仔细观察可以看到一些连线,这些连线把区域划分成了凸多边形与三角形。烘培时计算的主要信息正式这些凸多边形或三角形区域,以及每个区域与周围区域的连通关系。

导航系统的工作机制介绍:

在Unity官方文档中介绍了导航系统的工作原理,配合烘培后的网格来看不难理解。导航系统负责的工作从烘培开始,然后到具体的角色移动路线(包括移动中避障),到角色移动到目的地位置,主要分为以下4个步骤:

  1. 根据设置将地形或模型烘培,形成用很多凸多边形表示的“小平面”。这其中用到的主要算法是三角形剖分算法。
  2. 运行游戏时,在制定了起点和终点后,计算角色应当通过哪些面。这其中需要用到搜索算法,如常用的A*。
  3. 只有连通的平面的信息还不够,还需要形成具体的路线。这里的算法主要考虑的是各种拐角,尽可能按照距离最近而且平滑的路线移动,不能让角色绕得太远。
  4. 在具体移动的过程中,还需要考虑躲避动态障碍物,以及集体排队导航时互相阻挡得问题。

可以明显看到,生成的导航区域在地图边缘、墙壁边缘都有一定收缩。这是因为Nav Mesh Agent(可以理解为自动移动的角色)本身具有一定的半径,换句话说,由于角色有一定体积,角色的中心不可能紧贴在墙边。

不仅是宽度,代理得高度也会影响哪些区域能够通过,哪些不能通过,甚至斜坡的坡度、楼梯的高度也对能否通过有影响。在Bake标签页中也可以对这些参数进行设置。

1、烘培设置——导航代理的尺寸 

在导航系统的Bake标签页里,可以看到一个尺寸示意图。

虽然导航代理与场景烘培是两个不同的模块,但是Nav Mesh Agent的尺寸确实对烘培有影响,因此在烘培阶段就应该给出代理的参考尺寸。相关参数及其解释如下:

名称中文名称含义
Agent Radius角色半径代理的半径,如半径0.5m的角色无法通过宽度小于1m的通道
Agent Height角色高度代理的高度,代理无法通过低于此高度的通道
Max Slope最大坡度代理无法登上角度大于此值的坡度
Step Height台阶高度代理无法踏上高度大于此值的台阶
Drop Height最大掉落高度与自动生成导航链接有关,最大能从多高的高度跳下
Jump Distance最远跳跃距离与自动生成的导航链接有关,设定最远跳跃的距离

在修改这些参数时,既要考虑到场景尺寸,又要考虑到角色本身的尺寸,包括角色碰撞体的尺寸。通过合理的设置让可导航的路线符合游戏设计的需要,包括楼梯、坡道和通道等。

一般来说,角色的碰撞体积是用胶囊体表示的,这个胶囊体半径应该与代理半径一致或更小一些。例如,碰撞体半径大于代理半径,就可能出现导航系统认为能通过的窄路却被碰撞体阻挡的情况。再例如,角色站立时有1.8m,下蹲后可以通过0.9m的小洞,那么导航参数夜莺岛考虑到角色下蹲移动的情况。

2、烘培数据文件

当烘培完成后,再场景所在文件夹下,会多出一个与场景名称相同的文件夹,文件夹中有一个NavMesh.asset文件,里面就是烘培保存的数据了。

三、创建导航代理

烘培好Nav Mesh后,就可以添加Nav Mesh Agent了。Nav Mesh Agent也是一个组件,它可调整的参数比较多。下面先做一个可以随鼠标点击移动的例子。

  1. 创建一个胶囊体代表玩家,紧贴底面(已经烘培好的导航面)放置。
  2. 给胶囊体添加Nav Mesh Agent组件,默认参数即可。
  3. 创建脚本MoveTo,让物体向鼠标点击的位置移动。
  4. 将脚本挂载到胶囊提上,将摄像机升高并低头,改为半俯视角。
  5. 运行游戏,通过鼠标左键单击地面,胶囊体会朝着目标寻路移动。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class MoveTo : MonoBehaviour
{UnityEngine.AI.NavMeshAgent agent;void Start(){agent = GetComponent<UnityEngine.AI.NavMeshAgent>();}void Update(){if(Input.GetMouseButtonDown(0)){Ray ray = Camera.main.ScreenPointToRay(Input.mousePosition);RaycastHit hit;if(Physics.Raycast(ray,out hit)){agent.destination = hit.point;}}}
}

在运行游戏的同时打开导航烘培窗口,可以一边观察导航网格一边测试游戏,从而方便观察前往不同目的地的导航效果差异。特别是当单机没有被导航网格覆盖的白色区域时,物体依然会尽可能靠近目的地,停留在接近目的地的位置。

以上脚本通过摄像机发射射线,得到鼠标单击的位置。其操作导航代理的关键代码只有一条,如下所示:

agent.destination=hit.point;

只要设置了目的地,导航就会自动朝目标移动。

关于Nav Mesh Agent组件还有很多值得说明的参数和使用方法。下面先介绍Nav Mesh Agent组件的参数,再介绍Nav Mesh Agent组件的常用属性。

参数

说明名称中文名称说明
位置Base Offset中心偏移代理中心与物体中心点的y轴偏差距离。由于代理会自动贴在导航面上移动,如果有偏差就需要调节这个值。

Steering

(运动和

 转向)

Speed移动速度导航移动的速度受到此参数限制
Angular Speed角速度导航移动的转身速度
Acceleration加速度模拟角色由慢到快的加速度
Stopping Distance停止距离当离目标的距离小于此值时,就算到达了。此值控制允许误差的范围
Auto Braking自动刹车减速效果

Obstacle

Avoidance

(躲避障碍)

Radius避障半径躲避障碍时的自身半径参考值,较大的值代表尽可能远离障碍
Height避障高度避障时自身高度的参考值
Quality避障品质可调节避障算法的精度。精度越高,效果越好,对性能的影响也就越大
Priority避障优先级当多个代理一起避障移动时,数值小的代理优先级更高

属性

属性类型用途
hasPathbool当前是否有路径。也可以根据它判断是否到达目的地
isStoppedbool设置为true可以终止寻路
pathNavMeshPath获得当前路径对象
speedfloatNav Mesh Agent组件设置的速度,其他参数也可以用脚本控制
AngularSpeedfloatNav Mesh Agent组件设置的角速度
remainingDistancefloat当前位置到终点的位置
destinationVector3终点位置,设置它可以启动寻路
stoppingDistancefloatNav Mesh Agent组件的停止距离(即误差距离)
isOnNavMeshbool是否处于导航面上
velocityVector3代理当前实际运动的速度向量,非常有用的属性

以上属性都可以通过脚本读取或设置

四、导航障碍物

静态障碍物,如墙、水沟可以在烘培时就处理好,而在场景中动态添加的障碍物就无法预先烘培了。Nav Mesh Obstacle组件正是为标记动态障碍物而生的。其属性如图所示。

Nav Mesh Obstacle组件刻修改的参数不多,简单调整后即可使用。

障碍物的形状只有Box与Capsule两种。由于Nav Mesh Agent组件也有一定体积,因此没有必要定义精确的形状。选择形状后可以分别对位置、大小和半径等参数进行提及设置。

障碍物的存在会对导航产生影响,可选两种影响方式:阻碍和打洞。不勾选Carve选项就是阻碍,反之是打洞。

阻碍方式对导航层本身没有影响,就像是地图上的普通障碍物一样,Nav Mesh Agent组件会用规避算法尽量规避障碍物。阻碍方式的优点是不影响导航层,没有重新计算导航层的性能开销;缺点是规避效果取决于Nav Mesh Agent组件的具体移动,当障碍物较多、障碍物体积较大时,避障效果可能不会太理想。

打洞方式则会影响导航层本身的信息,就像是障碍物呗烘培到导航层上一样。Nav Mesh Agent组件在计算路径的阶段就会避开有洞的位置。

可以创建两个Nav Mesh Obetacle,测试勾选或不勾选Carve的效果。如图,上边是勾选的,下面是没有勾选的。

在开启导航窗口的情况下,两个Nav Mesh Obstacle的影响的区别显而易见。如果移动设置为打洞的那个障碍物,导航层会随之变化。

阻碍方式对性能影响较小,适合有一定运动速度、体积不太大的物体。打洞方式会引起导航层局部从新计算,带来一定的性能开销,因此适合于静态的、长期的地形变化。

例如,游戏中道路被掉落的石块堵死,适合用打洞方式实现;而角色过马路时路上的汽车等运动的小障碍,适合用阻碍方式实现。

下面介绍一下自动打洞设置。

在实际游戏中,障碍物的情况可能介于"快速变化"与"静止不变"之间,因此障碍物还支持更细节的控制。通过判断物体移动的距离和静止不动的时间,来确定打洞的时机,这一功能是通过Move Threshold(移动阈值)、Time To Stationary(固定时间)和Carve Only Stationary(仅固定时打洞)3个参数实现的。简单来说,在勾选了Carve Only Stationary的前提下,当物体移动距离超过了Move Threshold的值则取消打洞;当物体的静止时间超过了Time To Stationary的值,就可以被看作暂时固定,切换到固定状态时会进行打洞。

以上参数用文字解释比较抽象,有一个好方法可以快速直观测试这些参数的作用。

  1. 在一个烘培好的地形上放置两个导航障碍物,其中一个设置为打洞模式并勾选Carve Only Stationary,另一个设置为阻碍模式作为对照。
  2. 运行游戏,在场景中移动打洞障碍物的位置,当速度高于某个值时,导航的孔洞就会消失;当物体静止以后再经过一点时间,孔洞又会出现。这里的速度阈值和静止时间正是由Move Threshold和Time To Stationary分别控制的。

这些参数与实际游戏设计相关,只有在实际游戏开发中遇到了性能问题再仔细调整。通过这些参数可以控制大东的频率,平衡性呢个与导航效果之间的矛盾。

五、导航链接

游戏中的角色不仅会平面移动、爬楼梯和斜坡,有时还会跳跃,甚至瞬间移动。一旦有跳跃等情况,直接结果就是导航中会出现一些特例。第一种情况是走捷径,如角色不用走楼梯下楼,直接从二楼跳下更快。第二种 情况是直接跨越两个独立的导航面,走过导航面不连通的路径。

这种在原有导航面基础上添加的路径或捷径就是导航链接。如Unity支持自动生成导航链接和手动生成导航链接,下面分别简述其制作方法。

 1、自动生成导航链接

自动生成导航链接非常容易,先将所有静态导航物体设置为“可生成链接”,再在烘培窗口中设置角色的最大下落高度、最大跳跃距离,最后重新烘培即可,其具体操作如下。

  1. 打开Navigation窗口的Object标签页这个页面实际上是一个场景物体的过滤器,方便过滤和选择物体,如筛选所有具有网格渲染器的物体或所有具有地形组件的物体。无论是否过滤,只要在场景中选中所有需要生成导航链接的物体即可。例如,可以将前面所有设置为Navigation Static的物体选中,然后再在标签页中勾选Generate OffMeshLinks
  2. 完成之后回到Bake标签页,设置角色最大Drop Height和最远Jump Distance。为了效果明显,可以将它们的值设置得大一些
  3. 完成之后再次烘培,烘培结果中会出现很多小箭头,每个箭头都代表着一处导航链接。

 2、手动生成导航链接

自动生成导航链接很方便,但不易控制,很容易生成大量链接。如果仅在个别地方需要链接,建议手动生成导航链接。手动操作的方法很简单,步骤如下:

  1. 为了方便起见,新建一个空物体,位置归0
  2. 新建两个物体作为其子物体,这里分别命名为NodeA和NodeB
  3. 给父物体添加Off Mesh Link组件,Start设置为NodeA,End设置为NodeB
  4. 完成之后只要修改物体NodeA和NodeB的位置,就可以控制导航链接的位置了。为了方便查看和修改,可以在移动物体时打开Navigation窗口,这样就可以看到表示链接的箭头

这样生成的链接,使用时与自动生成的链接没有区别。

Off Mesh Link组件还有一个Bi Directional选项。勾选它表示既有正向链接也有反向链接,不勾选代表单向链接,只能从起点到终点,不能返回。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/72537.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

终端登录github两种方式

第一种方式 添加token&#xff0c;Setting->Developer Setting 第二种方式SSH 用下面命令查看远程仓库格式 git remote -v 用下面命令更改远程仓库格式 git remote set-url origin gitgithub.com:用户名/仓库名.git 然后用下面命令生成新的SSH秘钥 ssh-keygen -t ed2…

请大家一定不要像我们公司这样打印log日志

前言 最近接手了公司另一个项目&#xff0c;熟悉业务和代码苦不堪言。 我接手一个新项目&#xff0c;有个习惯&#xff0c;就是看结构&#xff0c;看数据库&#xff0c;搜代码。 其中搜代码是我个人这些年不知不觉形成的癖好&#xff0c;我下面给大家展示下这个小癖好。 正文 我…

vue3:3、项目目录和关键文件

关于vsvode的更改 <!-- 加上setup允许在script中直接编写组合式api --> <script setup> // 组件引入后直接用 import HelloWorld from ./components/HelloWorld.vue import TheWelcome from ./components/TheWelcome.vue</script><!-- 1、js放在最上面&am…

linux安装postgresql13

linux安装postgresql13 1. 安装2. 数据库初始化3.配置远程访问3.1 修改配置文件3.2 重启服务3.3 测试连接 1. 安装 linux下载链接&#xff1a;https://www.postgresql.org/download/linux/ubuntu/安装命令sudo sh -c echo "deb https://apt.postgresql.org/pub/repos/apt…

20230908_python练习_服务端与客户端数据交互

用户可以通过简单操作进行服务端数据交互&#xff0c;通过简单的sql语句直接获取EXCEL表&#xff0c;可以用来作为交互的基础。主要涉及三部分&#xff1a; 1:数据库存储表结构 --日志记录表结构 create table shzc.yytowz_service_title (leixing varchar2(18),ziduan1 v…

软件测试/测试开发丨学会与 AI 对话,高效提升学习效率

点此获取更多相关资料 简介 ChatGPT 的主要优点之一是它能够理解和响应自然语言输入。在日常生活中&#xff0c;沟通本来就是很重要的一门课程&#xff0c;沟通的过程中表达越清晰&#xff0c;给到的信息越多&#xff0c;那么沟通就越顺畅。 和 ChatGPT 沟通也是同样的道理&…

单目标应用:基于成长优化算法(Growth Optimizer,GO)的微电网优化调度MATLAB

一、微网系统运行优化模型 微电网是由分布式电源、储能装置和能量转换装置等组成的小型发配电系统&#xff0c;具有成本低、电压低、污染小等特点。由于环保和能源压力&#xff0c;清洁可再生能源和分布式能源工业发展潜力巨大。微电网控制器可实现对电网的集中控制&#xff0…

搭建RabbitMQ消息服务,整合SpringBoot实现收发消息

作者主页&#xff1a;Designer 小郑 作者简介&#xff1a;3年JAVA全栈开发经验&#xff0c;专注JAVA技术、系统定制、远程指导&#xff0c;致力于企业数字化转型&#xff0c;CSDN博客专家&#xff0c;蓝桥云课认证讲师。 目录 一、前言1.1 什么是消息队列1.2 RabbitMQ 是什么1.…

Linux:【Mysql】Centos7安装mysql8.0

目录 一、环境及版本介绍 二、安装前准备 三、开始安装 一、环境及版本介绍 Linux环境&#xff1a;Centos7 Mysql版本&#xff1a;8.0.26 安装时使用的用户&#xff1a;root 二、安装前准备 1.1、下载Centos7镜像 网上寻找相关资源即可 1.2、下载VMwareWorkstation Pro并…

【LeetCode-中等题】208. 实现 Trie (前缀树)

文章目录 题目方法一&#xff1a;利用数组构建26叉树方法二&#xff1a;利用哈希表构建26叉树 题目 方法一&#xff1a;利用数组构建26叉树 插入图示&#xff1a; 全搜索和前缀搜索&#xff1a; 注意&#xff1a;全局匹配匹配完直接返回插入时的标志位 而前缀匹配时&#xff…

OpenWrt系统开发笔记

openWrt英文官网&#xff1a; https://openwrt.org/ 中文官网&#xff1a; http://www.openwrt.org.cn/ 一、开发环境及编译 在github上有两个源码使用的比较多   一个是lede,地址为&#xff1a;https://github.com/coolsnowwolf/lede   另一个为OpenWrt的官方源码&#…

Redis 管道

1. 面试题 1.1 如何优化频繁命令往返造成的性能瓶颈? 1.2 问题由来 Redis是一种基于客户端-服务端模型以及请求/响应协议的TCP服务。一个请求会遵循以下步骤&#xff1a; 1 客户端向服务端发送命令分四步(发送命令→命令排队→命令执行→返回结果)&#xff0c;并监听Socket返…

Redis 复制(replica)

1. 是什么 1.1 官网地址 https://redis.io/docs/management/replication/ 1.2 一句话 1. 就是主从复制&#xff0c;master以写为主&#xff0c;slave以读为主 2. 当master数据变化的时候&#xff0c;自动将新的数据异步同步到其它slave数据库 2. 能干嘛 1. 读写分离 2. 容灾…

智能化电力运维:数字孪生的崭露头角

随着科技的不断发展&#xff0c;数字孪生技术在各个领域的应用愈发广泛&#xff0c;尤其在电力运维领域&#xff0c;它正发挥着革命性的作用。数字孪生是一种虚拟仿真技术&#xff0c;通过实时模拟真实世界的物理对象或过程&#xff0c;可以从多方面为电力运维带来改变&#xf…

PEX装机

目录 一、PXE是什么&#xff1f; 二、PXE的组件&#xff1a; vsftpd/httpd/nfs tftp dhcp 三、配置vsftpd 四、配置tftp 1.安装tftp-server 2.启动tftp 五、准备pxelinx.0文件、引导文件、内核文件 1.准备pxelinux.0文件 2.准备引导文件、内核文件 六、配置dhcp …

实时操作系统Freertos开坑学习笔记:(八):信号量、事件标志组、任务通知机制

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、信号量的简介1.信号量与队列的区别&#xff1f; 二、二值信号量及其实例1.什么是二值信号量2.二值信号量相关API函数3.二值信号量实例 三、计数型信号量四、…

TD3算法

TD3算法 全称Twin Delayed DDPG&#xff0c;是对DDPG算法的继承、发展和改进&#xff0c;论文 改进如下&#xff1a; T w i n \mathcal{T}win Twin&#xff1a;使用了两个critic来评估actor的动作价值&#xff0c;对应两个critic target&#xff0c;一个actor target&#xff0…

ChatGPT 超有用提示词 练习雅思口语

目录 Prompts &#x1f53b;作为一个英语口语老师和提高英语口语 方法1&#xff1a;口语简单练习 方法2&#xff1a;角色扮演练习口语 作为一个英语翻译/英语作文优化师/稿件校对 作为一个”职位”面试官 学习英文单词 演员 苏菲 玛索 阿尔弗雷多詹姆斯帕西诺 要孝顺…

联合教育部高等学校科学研究发展中心,阿依瓦科技创新教育专项正式发布!

7 月 24 日&#xff0c;教育部科技发展中心官网发布了《中国高校产学研创新基金&#xff0d;阿依瓦科技创新教育专项申请指南》。 针对高校在人工智能、智能制造、智慧校园、大数据等领域科研和教研的创新研究&#xff0c;教育部高等学校科学研究发展中心与阿依瓦(北京)技术有…

Android 自定义View之圆形进度条

很多场景下都用到这种进度条&#xff0c;有的还带动画效果&#xff0c; 今天我也来写一个。 写之前先拆解下它的组成&#xff1a; 底层圆形上层弧形中间文字 那我们要做的就是&#xff1a; 绘制底层圆形&#xff1b;在同位置绘制上层弧形&#xff0c;但颜色不同&#xff…