不知道为什么,就这个东西,国内各大论坛和网站就是搜不到。最终还是得谷歌

太过基础的就不讲了。

问题一: 在unity使用navmeshAgent进行多人寻路设置同一个终点后,所有角色都会向对应位置寻路,当前面单位到达后后面单位会一直无法到达导致阻塞甚至推挤。

简单的解决方案是给自己同时挂上navmeshAgent组件和navmeshObstacle组件,注意两个组件不能同时开启,否则会躲避自身导致胡乱移动。

在移动时关闭navmeshObstacle,使用navmeshAgent进行寻路。而达到目的地后则先关闭navmeshAgent,然后打开navmeshObstacle并开启carve属性,就会在寻路网格上挖洞,后来的单位则会重新寻路到附近可以走得地方就不会卡死了。

在攻击时使用这个解决方案也可以让后来得角色包围目标而不是挤在一起。

对应代码:

navMeshAgent.enabled = false;
navMeshObstacle.enabled = true;
navMeshObstacle.carving = true;

然后再要再次移动时再关闭挖洞,然后再打开寻路即可。

聪明的你应该猜到并写下了这么一段代码:

但是这其中有个问题:就表现上来说,角色会瞬移到之前挖好的洞旁边。看起来无法接受。

其中的原因是什么呢?

是因为这是在同一帧执行的,虽然写了关闭挖洞,但是在还没来得及真正的关闭挖洞就又打开了navmeshAgent,此时navmeshAgent判断自己不在寻路网格上,于是把自己移动到最近的寻路网格上就导致了顺义。

解决办法就是分为两帧执行,在一般的逻辑中这完全是可以接受的,因为从静止到移动确实需要花一些时间。

我因为是用了行为树所以写在了类似update的函数中,每次都会执行。你也可以直接改成协程。

private int frmeCount=0;
void Update(){
    if (frameCount == 1)//分为第0帧和第一帧,在关闭navmeshObstacle后的下一帧再开启navmeshAgent
        navMeshAgent.enabled = true;
        navMeshObstacle.carving = false;
        navMeshObstacle.enabled = false;
        frameCount=1;

当然,上面只是一段伪代码,自己注意启用条件之类的吧。

此外:如果你想各个单位能够更好的到达终点则每个单位的终点并不应该设置为同一个点,你可能需要根据每个角色的寻路半径来预先随机设置每个角色会到达的对应的位置,这样在寻路时才不会互相推挤。

关于这个算法我已经写好但是还在试验是否有遗漏的判断条件和优化空间,过几天我会更新相关的文章

图中的大白球代表坦克的终点,小白球代表士兵的终点

NavMesh是在实践中通用性最好的一种导航方式,但是Unity的实现并没有完全提供一个开放自由的API。 主要的麻烦是: 1.不能脱离Editor生成NavMesh。 2.NavMesh信息保存在场景中,必须随场景加载。 他的使用方式主要是在Editor阶段设定障碍关系。 1.在Agents移动到目的地附近时主动停止Agent的行动。 2.当所有NavMeshAgent.velocity.sqrMagnitude都小于某个值时,说明大家都来到了目的地。 代码... 通常情况下,静态的场景中,给场景物体静态标记中勾选Navigation Static后,在导航界面进行导航网格的烘培,可以得到一个静态的导航网格。 但是由于导航网格是静态烘焙好了的,游戏中动态生成的物体将不能阻挡导航网格的寻路,要想使这些动态生成的物体也能起到阻挡寻路的作用,需要给这些物体添加一个Nav Mesh Obstacle组件。该组建还要勾选上Carve属性,才能动态修改导航网格,不勾上的... 但是如果出现动态的障碍,比如一堵墙原本不能通过,现在又需要通过,这时候就需要用到Nav Mesh Obstacle,这里可能会想到空气墙,但是空气墙使用的是Rigidbody,如果速度过快可能就会出现穿过的问题。表示障碍物移动之后,等待多长时间,变为静止物体,然后去判断一次移动阈值,如果移动阈值不满足,同样不会生效到NavMesh,所以这里就是这个组件自己掌握性能优化的地方。Carve Only Stationary属性不勾选,那么静止时间没用,组件会每帧雕刻,消耗过大,但是移动阈值正常工作。 对于动态路障游戏对象,除了要设置 Navigation Static,还需要添加 NavMeshObstacle 组件,用于标记该对象在游戏运行过程中可以动态移动,以便 Unity3D 对此对象附近的导航网格进行动态烘焙。Carve:是否开启动态烘焙导航网格(当路障移动后,是否重新烘焙该路障附近的导航网格); Move Threshold:当路障移动的距离超过此阈值时,才会触发重新烘焙该路障附近的导航网格; Time To Stationary:路障静止多长时间后才会触发重新烘焙导航网格; Carve On 对于上一节中的示例,如果一个游戏场景中包含很多的桥,每个桥都有自己的通行或禁止状态,那么就需要为每一个桥分一个层,这样层数就可能不够用了,因为在Unity中最多只有32层。其次在行进物体很多的时候频繁更改行进物体的可行进层也不是一件轻松的事。Unity提供了另外一种Navmesh Obstacle组件,它更适合处理类似动态路障的问题。将该组件挂载在动态路障上时,行进物体就会在寻路时躲避这些路障。 ... 当navmesh导航网格烘焙好之后,又要想添加阻挡时,就是使用NevMeshObstacle来实现。 1、模型添加NevMeshObstacle就变成了一个动态障碍物,这样在导航网格上,根据模型的大小,挖出一个“洞”,使模型范围内的导航网格消失,这样NavMeshAgent就不能经过次区域了,移动障碍物,会从新挖“洞”。 2、NavMeshObstacle参数: (1)、Move Threshold:该参数代表该障碍物的移动的极限距离超过这个参数时,才会重新雕刻这个障碍物。增大此值,障碍物移动没有超过这个 NavMesh(导航网格)是3D游戏世界中用于动态物体实现自动寻路的技术。 NavMesh系统是人工智能的一种,它使用一个添加在游戏对象上或者作为游戏对象父物体的名为“导航网格代理”(NavMeshAgent)的组件来控制该游戏对象寻找能够通过的路径,并最终到达目的地。 自动寻路还可以实现绕过障碍、爬上与跳下障碍物、按类别寻找属于自己的道路、动态设置道路中的障碍等技术。 下面用一个简单的Demo来介绍NavMesh的应用: 1.在Scene场景中添加Cube设置场景,如图所示: 2.选择除了主角、目标以及摄像机、直线光以外的所有物体,在Inspector窗口的右上角勾选Static,成为静态 这个组件放在场景中的导航网格上,可以阻挡NavMeshAgent的移动。以Unity4.3.4为例。 NavMeshObstacle 分为两种模式,一种是普通模式,通过设置半径和高度来确定一个范围,阻档NavMeshAgent移动,一种是Carve模式,在导航网格上,根据模型的大小,挖出一个“洞”,使模型范围内的导航网格消失,这样NavMeshAgent就不能经过... 动态导航寻路就是在AI寻路过程中,如果原先有障碍物的地方障碍物消失或移动位置后,原来障碍物的位置变为可移动,新的障碍物位置变为不可移动 实现动态NavMesh导航有两种方法,一种是使用Unity自带的NavMeshObstacle组件,另一种是官方出的一种更高级的动态寻路方案,高级的动态寻路方案在性能上消耗太大,一般情况下不推荐使用 二:效果演示 三:方法1—NavMeshObstacle组件 正常在Navigation窗口中烘焙场景,属于障碍物的游戏物体挂上NavMeshObsta