找回密码
 立即注册
查看: 707|回复: 0

Unity寻路插件(A* Pathfinding)入门教程十三:2D中的寻路

[复制链接]
发表于 2020-11-25 09:21 | 显示全部楼层 |阅读模式
本系列的教程文章基于 A*Pathfinding Project 4.2.8的官网教程翻译,每一章节的原文地址都会在教程最下方给出。
这篇教程将讲解怎么在2D游戏中寻路。
插件里一共提供了2个介绍2D寻路相关的场景。Example15_2D 和 Example16_RVO 2D。
创建一个2D游戏的寻路其实有很多种方法,下面这两种是比较常见的方式:
    自顶至下(Top-down),大概就是俯视世界的一种方式,就是上面图片展示的方式。平台式寻路(Platformer),类似于马里奥。遗憾的是,目前这个插件尚不支持这种寻路……不过你可以使用很多的路点,然后创建一个自定义的连接(connections)去实现,但是这并不能通用。
这里有个视频,可以教你怎么使用寻路创建一个简单的2D场景。(爬墙)
Graph 支持

    gird graph 和layered grid graph 可以很好的在XY面工作。实际上,grid graph也可以旋转到任何方向,并且它仍然能够正常工作。对于2D游戏来说,你应该勾选grid graph上的2D按钮,这样就会自动帮你旋转graph,与XY面成一条直线。如果你想用2D的碰撞,你也需要勾选Use 2D Physics 的按钮。Point graphs 也支持XY面的寻路。和gird类型的一样,如果你需要使用Raycast或者使用2D 的物理碰撞,也要勾选Use 2D Physics按钮。Recast graphs 也可以被旋转到XY平面,或者其他任何角度。但是他们并不支持2D的碰撞体,也不支持使用sprites作为栅格输入的处理。如果你用这场的网格是没有什么问题的。Navmesh graphs 的原理和 recast 类似。所以他们都支持任何角度的视角。但是你需要注意要保持 graphs的“up”和希望的“up”方向一致。比如,如果你想用navmesh在XY平面上工作,你需要将rotation字段设置到(-90,0,0),当然你不能简单的在may或者Blender软件里直接旋转mesh。
Graph 更新(Graph updates)

Navmesh Cutting
Navmesh 裁切可以用来更新2D或者任何其他方向的 navmesh 或者 recast类型的graph。但是要注意,navmesh cuts的旋转也要正确。navmesh cuts用一个2D的轮廓来表示,这些轮廓会投影在graph的表面。如果navmesh cut的旋转信息错误,那么它投影的方向就只有一条线,那么就不能正确的裁切graph。如下图:
当你使用一个非水平的Graph的时候,useRotationAndScale的选择框必须勾选上才能保证正常工作。
2D Colliders
当使用graph updates的时候,3D游戏中一个常用的做法就是:
  1. var guo = new GraphUpdateObject(GetComponent<Collider>().bounds);
  2. // change some settings on the object
  3. AstarPath.active.UpdateGraphs(guo);
复制代码
但是在2D游戏中使用了 2D Colliders 的方式,上面的代码就会失效。原因是2D的Colliders可以认为是无限薄的,所以它的bounds的体积会是一个0。所以当要判定一个节点是否在某个边界(bounds)里的时候,那么永远不会命中,因为你没法在一个没有体积的物体里放进任何东西。解决这个问题的方式就是,扩展这个bounds的Z轴,让他能够包含所有的节点。
  1. var bounds = GetComponent<Collider2D>().bounds;
  2. // Expand the bounds along the Z axis
  3. bounds.Expand(Vector3.forward*1000);
  4. var guo = new GraphUpdateObject(bounds);
  5. // change some settings on the object
  6. AstarPath.active.UpdateGraphs(guo);
复制代码
移动脚本(Movement scripts)

AIPath支持Grid graphs、navmesh graphs、recast graphs类型的任意方向,它会自动检测方向。不过,你需要禁用gravity选项,以防止这些物体因为重力从map掉下来~而Point graphs没有定义“up”方向,所以AIPath就不知道怎么去定位方向了。如果你知道方向的话,你可以代码里设定变量来强迫AIPath寻路。
  1. // In the AIPath.cs script, find the line that looks like
  2. // movementPlane = graph != null ? graph.transform : GraphTransform.identityTransform;
  3. // and replace it with
  4. var graphRotation = new Vector3(-90, 0, 0);
  5. movementPlane = new GraphTransform(Matrix4x4.TRS(Vector3.zero, Quaternion.Euler(graphRotation), Vector3.one));
复制代码
    graphRotation 可以改变成任何你想要的方向。RichAI 暂时不支持除XZ平面上的其他方向。但是,我们已经做相当多的工作来让他支持,并且已经完工了,希望早点在下个版本里发布。AILerp 支持任何的graph方向。对于许多2D游戏来说,他们可能希望+Y轴为前方,而不是3D里常用的+Z轴。如果这样的话,你只需要勾选rotationIn2D选框。
局部回避(Local avoidance)

局部回避,在XY平面工作。你仅需要做一件事,就是改变movementPlane设置里的RVOSimulator组件到XY。可以查看插件的示例Example16_RVO 2D 来看他是怎么配置和运作的。
原文链接:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
懒得打字嘛,点击右侧快捷回复 【右侧内容,后台自定义】
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Unity开发者联盟 ( 粤ICP备20003399号 )

GMT+8, 2024-11-27 12:00 , Processed in 0.114723 second(s), 28 queries .

Powered by Discuz! X3.5 Licensed

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表