相关文章推荐
奋斗的机器人  ·  Unity ...·  8 月前    · 
严肃的火锅  ·  使用 XPathNavigator 导航 ...·  1 年前    · 
爽快的小蝌蚪  ·  导航栏(navbar) - ...·  1 年前    · 
强健的馒头  ·  nginx ...·  1 年前    · 
爱笑的西红柿  ·  cv2.minAreaRect(cnt) ...·  1 年前    · 
很酷的钢笔  ·  [系列] go-gin-api ...·  1 年前    · 

立即停止寻路

  • 使用agent.isStopped=true,可以停止寻路,但是有很大的延迟,视觉体验很不好。

  • 使用agent.enabled=false,通过禁用NavMeshAgent组件的方式实现立即停止寻路。因为组件被禁用可能会产生其它问题,比如失去了Obstacle Avoidance的功能。

  • 使用agent.ResetPath(),可以停止寻路,同isStopped一样,会有很大延迟。

  • 使用agent.destination = agent.transform.position;虽然看起来很尴尬,但是可以满足需求。

  • 使用carve,即需要为物体添加NavMeshObstacle组件,在需要停止的时候启用该组件,并设置Carve为true,同时关闭NavMeshAgent(NavMeshObstacle和NavMeshAgent两个组件无法共存)

navAgent.SetDestination(point)

若目标点point不可达,这会为你分配一个当前Navmesh上一个离目标point最近的可达点。若无可达点,这返回false。

SetDestination缓慢的问题

若有大量的角色同时寻路,且伴随carve的重建,那么寻路会很耗时,表现出的结果就是角色很卡,可以通过设置 NavMesh.pathfindingIterationsPerFrame 为一个很大的值来规避。
SetDestination本身是一个异步方法,unity默认是限制了其每帧执行的次数的。通过上述设置提高了每帧执行的次数,但是本质上它还是一个单线程的方法。当角色海量时,还是会大大降低游戏帧率的。

 NavMeshPath path = new NavMeshPath();
                    agent.CalculatePath(targetPos, path);
                    if (path.status == NavMeshPathStatus.PathComplete)
                        //reachable
                        agent.SetPath(path);
                        //agent.SetDestination(targetPos);//already CalculatePath,so use SetPath is more effective than SetDestination
                        //not reachable

设置多个寻路层

  • 比如需求是寻路层有:普通道路、桥。
  • 自带的默认层有Walkable、Not Walkable、Jump。在Navigation->Areas下增加新层Bridge。注意这个界面中每层的颜色最终也反应在烘焙网格的Gizmos显示中。流程如下:
    • 1,为桥所在的物体添加NavMeshModifier,设置其Area Type属性为Bridge。桥所在的物体选中后,打开Navigation->Object,设置其Navigation Area为Bridge。其它行走区域设置Navigation Area为Walkable,障碍区域设置Navigation Area为Not Walkable
    • 2,NavMeshSurface烘焙行走区域
    • 3,为NavmeshAgent设置可行走区域,如:agent.areaMask = 1 << 0 | 1 << 3;
  • 从指定点找到导航网格中的最近点

NavMesh.SamplePosition(Vector3 sourcePosition, out AI.NavMeshHit hit, float maxDistance, int areaMask),bool True if the nearest point is found.参考:NavMesh.SamplePosition

NavMeshAgent寻路单位重叠(大量带有NavMeshAgent的单位寻路到相同点时,在寻路过程中会重叠,到达目标点后也会重叠)

方法一,使用Obstacle Avoidance。

文档中说Obstacle Avoidance使用的rvo,但是效果不是太好,实测不同物体之间碰撞后产生的推挤、抖动很严重。
如果你想各个单位能够更好的到达终点则每个单位的终点并不应该设置为同一个点,你可能需要根据每个角色的寻路半径来预先随机设置每个角色会到达的对应的位置,这样在寻路时才不会互相推挤。

方法二,使用NavMeshObstacle来挖洞。

具体流程是给物体同时挂上NavMeshAgent(不开启Obstacle Avoidance)和NavMeshObstacle组件(注意两个组件不可同时开启否则会产生不可控的瞬移)。在移动时关闭NavMeshObstacle组件,启用NavMeshAgent进行寻路;在到达目标点后先关闭NavMeshAgent,再启用NavMeshObstacle组件来挖洞,这样会对Navmesh路网进行重建,其它物体寻路路线也会变化最终会绕着目标形成包围圈。

根据上述内容知道,物体挖洞后再恢复寻路则需要禁用NavMeshObstacle,并启用NavMeshAgent。相关伪代码如下:

navObstacle.enabled=false;
navObstacle.carving=false;
navAgent.enabled=true;

然而事实是这样的话也会使物体发生不可控的瞬移,原因就是NavMeshObstacle的禁用不是立即完成的,上述代码会导致在当前帧NavMeshObstacle、NavMeshAgent都处于开启状态。因此在禁用NavMeshObstacle后必须至少延迟1帧才能开启NavMeshAgent。

参考:https://github.com/llamacademy/ai-series-part-33

git上一个基于dots的nav寻路:https://github.com/dotsnav/dotsnav

然而事实是这样的话也会使物体发生不可控的瞬移,原因就是NavMeshObstacle的禁用不是立即完成的,上述代码会导致在当前帧NavMeshObstacle、NavMeshAgent都处于开启状态。如果你想各个单位能够更好的到达终点则每个单位的终点并不应该设置为同一个点,你可能需要根据每个角色的寻路半径来预先随机设置每个角色会到达的对应的位置,这样在寻路时才不会互相推挤。若有大量的角色同时寻路,且伴随carve的重建,那么寻路会很耗时,表现出的结果就是角色很卡,可以通过设置。为一个很大的值来规避。
教程地址 :https://www.bilibili.com/video/BV1b5411P7NE?spm_id_from=333.1007.top_right_bar_window_custom_collection.content.click 根据视频教程写的工程
DotsNav是基于DOTS构建的完全动态且健壮的平面导航网格Unity软件包。 它足够快地在每个帧中添加和删除许多障碍,支持任何规模的代理,并且可以通过单行为来使用,而无需事先了解DOTS。 DotsNav处于开发的早期阶段。 它通过了苛刻的鲁棒性测试(如视频和演示所示),但仅在开发演示时才使用。 DotsNav可以作为Windows独立的UWP应用程序运行,也可以在Android上运行。 Apple设备尚未经过测试。 为了支持进一步的开发,请考虑成为赞助者,并可以访问比该存储库要早几个月的Beta和开发存储库,还可以访问私有不和谐频道并对该投票。 第一个改进将是通过移植来实现局部回避。 Unity的最低要求版本是2020.1.6f1。 推荐的安装DotsNav的方法是通过OpenUPM unitypackage安装程序(右上方)。 下载安装程序后, 在使用导航组件时如果报错:"SetDestination" can only be called on an active agent that has been placed on a NavMesh,这个报错信息的重点其实并不在导航组件是否active 游戏运行后使用Instantiate方式将实例化物体,再改变其初始位置,使得物体在实例化的一瞬间距离导航网格过远,使得导航失效 GameObject go = Instantiate(prefab); go.transfor
问题:"SetDestination" can only be called on an active agent that has been placed on a NavMesh. 原因:导航NavMeshAgent组件所在物体距离Navmesh导航网格太远,'NavMeshAgent.SetDestination'设置导航目标点失败 解决:在设置导航目标点之前,可以用‘NavMeshA...
前言:Unity版本为2019.2.9f1 Ppersonal。Unity版本可在上方Help下点击About Unity找到。本文将采用官方文档的英文对比介绍,一些相对简单的参数就不引用官方文档了。由于个人英文水平有限,翻译不到位的地方还请原谅。个别方法鉴于目前还没使用过,不好做过多介绍,只好先贴出来以供暂时理解即可。看完觉得有帮助还请点个赞,还想看其他文章的也请加个关注哦~喵。 文章目录N...
哪个物体需要寻路就在哪个物体上加一个Nav Mesh Agent组件,主要介绍一下steering下的参数,一个是寻路速度,最大的加速度,角速度,以及制动距离。这几个参数可以让你的寻路更加的圆滑,推荐大家自己去调的时候用一下。 使用前需要对场景先进...
原因:初始化导航组件NavMeshAgent 的时候,agentnavmesh太远。isOnNavMesh属性为false; 解决办法: 在初始化预制体的时候,传入诞生点位置和旋转信息。 GameObject.Instantiate(m_shooter, m_currBirthPoint.transform.position,m_currBirthPoint.transform.rotatio...
官方文档:https://docs.unity3d.com/Manual/StreamingAssets.html 这是一个只读、不可写的目录。 官方推荐使用Application.streamingAssetsPath来获得该文件夹的实际位置,其可以规避平台差异。 对于ios平台,其等价于:Application.dataPath + "/Raw"; 对于android平台,其等价于:"j.........
Unity粒子系统插件是一种强大的工具,用于创建和管理游戏中的粒子效果。它为开发者提供了丰富的功能和灵活性,可以实现各种视觉效果,提升游戏的质量和吸引力。 Unity粒子系统插件可以通过创建和编辑粒子系统来生成各种粒子效果。开发者可以通过调整粒子的速度、大小、形状、旋转、颜色等属性,来实现不同的效果。插件还支持添加纹理、光照、阴影等特效,让粒子效果更加逼真和细腻。 另外,Unity粒子系统插件还提供了丰富的粒子发射器和发射模式选项。开发者可以选择不同的发射形式,如点发射、圆形发射、线性发射等,以及发射器的持续时间、速度、密度等参数。这些选项可以帮助开发者实现更精确的粒子控制和定制。 Unity粒子系统插件还支持粒子系统的运动和碰撞效果。开发者可以通过添加力场、重力、引力和限制器等设置,实现各种动态的粒子行为。插件还支持粒子的碰撞检测和反弹,让粒子可以与场景中的物体进行交互,增加了游戏的可玩性和真实感。 总之,Unity粒子系统插件是一个功能强大的工具,为开发者提供了创建和管理游戏中粒子效果的高效方式。它的灵活性和可定制性使得开发者能够实现各种各样的粒子效果,提升游戏的视觉效果和用户体验。