With test_motion
我不建议用RigidBody2D
碰撞,因为并非每次碰撞都意味着它在地面上(例如可能撞到墙壁或天花板)。
但是,还有另一种方法:您可以使用test_motion https://docs.godotengine.org/en/stable/classes/class_rigidbody2d.html#class-rigidbody2d-method-test-motion。如果运动会导致碰撞(当然,没有实际移动),则返回 true。
So use test_motion
向下,如果检测到碰撞,则意味着RigidBody2D
位于地面上:
if Input.is_action_just_released("ui_up") and self.test_motion(Vector2(0, 1), false):
apply_central_impulse(Vector2(0,-1000))
With RayCast2D
另一个简单的设置是使用RayCast2D
反而。将其定位为从底部向下延伸CollisionShape2D
or CollisionPolygon2D
of the RigidBody2D
。确保RayCast2D
已启用。然后您可以检查是否RayCast2D
正在碰撞来决定是否RigidBody2D
可以跳跃:
if Input.is_action_just_released("ui_up") and $RayCast2D.is_colliding():
apply_central_impulse(Vector2(0,-1000))
考虑使用上述方法,如果RayCast2D
未能检测到某些东西,RigidBody2D
将无法跳跃。例如,如果RayCast2D
是居中的,但是RigidBody2D
仅部分位于地面上,因此RayCast2D
什么也没击中。
With Area2D
另一种选择是使用Area2D
代替RayCast2D
。其优点是拥有自己的CollisionShape2D
or CollisionPolygon2D
。您需要统计进入或存在的尸体数量Area2D
:
var on_ground := 0
func _on_Area2D_body_entered(body: Node) -> void:
on_ground += 1
func _on_Area2D_body_exited(body: Node) -> void:
on_ground -= 1
当然,在你的检查中使用它来跳转:
if Input.is_action_just_released("ui_up") and on_ground > 0:
apply_central_impulse(Vector2(0,-1000))
最后我提醒你,你有碰撞层和碰撞蒙版。用一个RayCast2D
or an Area2D
允许你设置一个与之前的不同的掩码RigidBody2D
用途。这是指定并非所有事物的一种方式RigidBody2D
与物体碰撞,它可以从中跳出。
I find Area2D
更加可靠和多功能。然而,设置工作量更大。