Godot-StartUP

创建于:2018-07-28

创建人: Justus

44 信息 140 成员
讨论基于Godot以及Unity引擎的游戏开发经验,理论和最佳实践。共享一些通用思路以启发另一种生产工具中的实践。独立开发群QQ: 122017359

[godot]navigation2d的一些坑

廿木 2018-08-07

近日在做navigation2d加navigationPolygonInstance做寻路的时候遇到了一些坑,先记录下来。

使用的示例是官方自带的navigation2d示例,脚本没有进行修改,只改了相关的navigationPolygonInstance

1.如果在navigation2d的子孙节点里有多个NavigationPolygonInstance,且这些NavigationPolygonInstance不粘连,而当get_simple_path( Vector2 start, Vector2 end, bool optimize=true )传入的start和end跨越两个不粘连的NavigationPolygonInstance时,该函数不起作用,不过有时候也能以小概率在NavigationPolygonInstance的边缘卡进另外一个NavigationPolygonInstance。

如图:在navpoly和navpoly2不粘连的时候,即使是重叠,也不能使agent跑到navpoly2的区域上去

Image title


2.即使多个NavigationPolygonInstance紧贴在一起,如果紧贴的地方没有重合的顶点,则get_simple_path()函数返回绕过没重合顶点的路径数组,假如两个NavigationPolygonInstance完全没有重合顶点,则造成了问题一

下图为2个navpoly的形状,可以看到只有一对重合顶点。

Image titleImage title



最终运动效果:

Image title


结论:

1.要想navigation2d对所有子节点的navigationPolygonInstance起作用,就要让它们有重合的点

2.最好用“依附”功能Image title来做重合,因为navigationPolygonInstance里的每个顶点都是一个vector2,向量你懂的,xy都可以是小数,不知道算重合的精度是多少。




.............................

另外一个坑其实算小进阶,就是在已有的navigationPolygonInstance里挖个不能走的坑,比如你要在地图上放一个花盆,AI要绕过去,又不想手动改navigationPolygonInstance,就代码改改。

这个问题我在下面这个网址上看到的

https://www.reddit.com/r/godot/comments/7k4qos/why_does_this_script_created_hole_in_the/

然后试了下里面的代码,其实还有点旧了,可能那时候还没to_local和to_global函数,就还是用transform的逆矩阵乘另一个transform来获取本地transform,但这种方法也有局限性,说起来还挺麻烦,不说了,知道有局限就好(想了解矩阵的相关知识的可以点一下

https://www.bilibili.com/video/av6731067

这个b站的链接)。

再然后根据里面的代码改了下项目唯一的脚本navigation.gd:

1.添加变量Cutout,类型是polygon2d,在场景中添加一个polygon2d节点,弄个形状,使Cutout变量指向这个节点。

2.添加函数:

#调节polygon2d的位置

func adjustPolygonPosition(inTransform, inPolygon):

    var outPolygon = PoolVector2Array()

    #把顶点转换到本地坐标,要求navpoly和cutout要有相同的父节点,或各自父节点的transform相同

    #var finalTransform = $navpoly.transform.inverse() * inTransform

    for vertex in inPolygon:

        #outPolygon.append(finalTransform.xform(vertex))

        #下面这个方法就没有父节点限制

        var finalPos = $navpoly.to_local(Cutout.to_global(vertex))

        outPolygon.append(finalPos)

return outPolygon

#重新修改节点

func modifyNavPoly():

    #其实outline就是顶点数组,输出一下就知道了

    $navpoly.navpoly.add_outline(adjustPolygonPosition(Cutout.transform, Cutout.polygon))

    $navpoly.navpoly.make_polygons_from_outlines()

    #下面这些是必须的,用于更新navpoly

    $navpoly.enabled = false

    $navpoly.enabled = true

3.在_ready()里添加一行代码:

modifyNavPoly()

就ok了,要注意的是,cutout不能挖到navpoly外面,不然就没效果。

下图是我的节点结构:

Image title


把cutout放在Node2D下面是为了测试我自己改了的代码和原本的代码有没有区别,可以移动一下Node2D节点对比下新旧代码效果。

navpoly就是被挖的NavigationPolygonInstance,而navpoly2是我测试看两个粘合的NavigationPolygonInstance能不能一起挖,发现是不能的。

至于再怎么填回去。。。

Emmm

我自己也没做,但可以猜测下。

首先NavigationPolygonInstance的get_outline(0)返回的是本身的顶点数组,然后每调用一次add_outline()就会使outline数加一,也就是这时候用get_outline(1)会获得新加上去的顶点数组,然后你就可以用remove_outline()函数来试试咯。


另外,如果各位小伙伴在测试上面这些内容的时候发现有问题请留言!我看到会马上改的!万分感激!

(转发自:原日志地址
 

加入 indienova

  • 建立个人/工作室档案
  • 建立开发中的游戏档案
  • 关注个人/工作室动态
  • 寻找合作伙伴共同开发
  • 寻求线上发行
  • 更多服务……
登录/注册