目录
- RigidBody2D
- 添加节点
- 如何悬停
- 如何开始坠落
- 触发坠落
- 触发范围
- 触发坠落
- 触发对象,Layer和Mask
相信看了开始的图,大家都知道本文的内容。基础问题就两个:
- 如何触发
- 如何下坠
这里我们倒过来,先说说如何下坠的问题。想要一个对象下坠有很多的方法,Godot提供的节点中就有非常适合的,它就是 RigidBody2D 。
RigidBody2D
RigidBody2D 一般称做钢体,它的主要功能是自动受物理引擎控制,比如引力,碰撞。这意味着,只要没有物体和它产生碰撞,它就会一直下落。是不是非常符合这个需求。
那么一个问题就来了,既然自动受物理引擎控制,如何静止不动呢?
添加节点
首先,我们将 RigidBody2D 节点添加进来。
创建一个新场景 Fall ,使用 Node2D 作为根节点,命名为 Fall ,并添加子节点 RigidBody2D 。
可以看到,有警告提示,如何有用过类似节点(如: KinmaticBody2D )就知道,它需要一个碰撞体。不过,我们先添加一个形状来代表坠落物体,不然,碰撞体附在哪里呢?
以下内容为示例内容,并不一定需要这样的节点,可以用 Sprite 等其它节点代替 。
为 RigidBody2D 节点添加子节点 Polygon2D 。
并为其创建图形。
注:如果不清楚如何创建图形,可以看看别的文章。
接着创建一个碰撞体 CollisionShape2D ,并为它添加一个形状。调整大小覆盖住多边形。
那么,坠落物就做好了。保存后,将Fall场景拖入主场景,运行游戏,可以看到,它在做自由落体运动。
如何悬停
其实不用多说,坠落就是受到引擎的重力,只要将重力置为0就可以了。
回到 Fall 场景,选中 RigidBody2D 节点。将 Inspector > Gravity Scale 的值设置为 0 。
再次运行游戏,它已经不再下坠了。
如何开始下坠
知道悬停是如何产生之后,想要下坠肯定第一想到的就是将 Gravity Scale 设置为1。但是,可能并不能入你愿,这里需要牵扯到它的另两个属性。 Sleeping 和 Can Sleep (其实在这里只需要Can Sleep)。先看看引擎对Can Sleep的说明:
意思是当它没有移动的时候,它将进入sleep模式,直到产生碰撞或是给它一个力 。
那么,开始时,我们没有给它重力,它是静止的,所以在默认情况下,它已经进入了sleep模式,因此,如是仅仅为它恢复重力,它是不会受到重力作用开始下坠的。
要怎么做就显而易见了,初始将它的重力置为0的时候,也取消 Can Sleep 。这样坠落物不会进入sleep模式,当我们为 Gravity Scale 赋值后,它将开始下坠。这一操作,我们将在 触发 部分进行说明。
触发坠落
条件其实非常简单,只要角色移动到一个范围里,坠落物就开始下坠,所以,我们需要一个可以检测的区域,这个区域可以使用 Area2D 节点,它可以探测也可以影响物理事件,但它不会产生碰撞。意思是它能够探测到物理对象进入了Area2D的范围,但不会将它推走。
触发范围
那么在 Fall 场景添加子节点 Area2D ,并为它添加一个形状,形状如下图,大小可根据情况设定。
触发坠落
上面已经讲到,只要角色进入Area2D区域就触发坠落,这将用到信号。
选中 Area2D 节点,打开 Node 面板,选中 Signals ,找到 body_entered ,双击它。选择 RigidBody2D 的脚本,为其添加函数 _on_Area2D_body_entered (如果RigidBody2D还没有脚本,先为他添加一个脚本)。在方法中添加如下代码:
func _on_Area2D_body_entered(body):
gravity_scale = 1
保存后运行游戏,角色靠近后,坠落物下落。
触发对象
我们试着多添加几个坠落物,让触发区域做一些重叠。运行游戏后会发现,坠落自动触发了。
这是因为 Area2D 的 body_entered 被TileMap相互触发了。解决这个问题,就是 Layer 和 Mask 。
- Layer :表示当前节点所在层
- Mask :表示当前节点可以产生碰撞的目标层
举个例子,A节点的Layer是1,Mask是1。B节点Layer是1,Mask2,C节点Layer是2,Mask是2。那么A节点可以和B节点产生碰撞,B节点可以和C节点产生碰撞,但是A节点和C节点则不会有碰撞。
那么,看看几个需要产生碰撞节点的Layer和Mask。
- TileMap:Layer=1,Mask=1
- Player:Layer=1, Mask=1
- Area2D:Layer=1,Mask=1
所以,Area2D不仅会和Player产生碰撞,也会和TileMap产生碰撞,而我们的Area2D比较长,添加到场景中就已经和TileMap交织在了一起,如图:
所以游戏一运行就产生的坠落。解决问题非常简单,对Layer和Mask设置不同的值。
- TileMap:Layer=1,Mask=1
- Player:Layer=1和2,Mask=1和2
- Area2D:Layer=2,Mask=2
其中Player的Layer和Mask为1和2的目的是让它即和TileMap产生碰撞,也可以和Area2D产生碰撞。因为TileMap和Area2D所在层和目标层都不同,所以它们不再产生碰撞。
再次运行游戏。
结论
Godot3已经提供了非常棒的节点特性,用于处理一些物理效果非常简单。本文只是说明了RigidBody2D作为坠落物时的一些处理方法,坠落时和坠落后的一些效果,如抖动,爆炸后面会有相关文章说明。
下次将聊聊RigidBody2D更合理的物理特性处理。(默认状态下,它的物理特性其实不是那么正常)。
结束