问题描述
我会使用运动学身体,但我想为我的 2d 对象添加现实生活中的物理,但似乎我可以通过按几次向上键来飞行
I would have used a kinematic body but i want to add real life physics to my 2d object but it seems that i can literally fly by pressing the up key several times
extends RigidBody2D
var velocity = Vector2.ZERO
const GRAVITY = 35
const SPEED = 1000
const JUMPFORCE = -900
func _process(delta):
if Input.is_action_just_pressed("ui_right"):
apply_central_impulse(Vector2(1000,0))
if Input.is_action_just_pressed("ui_left"):
apply_central_impulse(Vector2(-1000,0))
if Input.is_action_just_released("ui_up"):
apply_central_impulse(Vector2(0,-1000))
推荐答案
使用test_motion
我不建议使用 RigidBody2D
碰撞来处理这个问题,因为并非每次碰撞都意味着它在地面上(例如可能会撞到墙壁或天花板).
With test_motion
I do not recommend handling this with the RigidBody2D
collisions because not every collision means it is on the ground (e.g. could be hitting a wall or ceiling).
但是,还有另一种方法:您可以使用 test_motion
.如果移动会导致碰撞,则返回 true(当然,实际上并没有移动).
However, there is another way: you can use test_motion
. It returns true if a movement would result in a collision (without actuallyu moving, of course).
所以使用 test_motion
向下,如果检测到碰撞,则表示 RigidBody2D
在地面上:
So use test_motion
downwards, if it detects a collision, it means the RigidBody2D
is on the ground:
if Input.is_action_just_released("ui_up") and self.test_motion(Vector2(0, 1), false):
apply_central_impulse(Vector2(0,-1000))
使用 RayCast2D
另一个简单的设置是使用 RayCast2D
代替.将其定位为从 RigidBody2D
的 CollisionShape2D
或 CollisionPolygon2D
的底部向下延伸.确保 RayCast2D
已启用.然后你可以检查 RayCast2D
是否碰撞来决定 RigidBody2D
是否可以跳跃:
With RayCast2D
Another simple setup is using RayCast2D
instead. Position it to extend downwards from the the bottom of the CollisionShape2D
or CollisionPolygon2D
of the RigidBody2D
. Make sure the RayCast2D
is enabled. Then you can check if the RayCast2D
is colliding to decide if the RigidBody2D
can jump:
if Input.is_action_just_released("ui_up") and $RayCast2D.is_colliding():
apply_central_impulse(Vector2(0,-1000))
考虑到上面的方法,如果RayCast2D
没有检测到什么东西,RigidBody2D
将无法跳转.例如,如果 RayCast2D
居中,但 RigidBody2D
只是部分在地面上,这样 RayCast2D
什么也没有击中.
Consider that with the above method, if the RayCast2D
fail to detect something, the RigidBody2D
won't be able to jump. For example, if the RayCast2D
is centered, but the RigidBody2D
is only partially on the ground, such that the RayCast2D
hits nothing.
另一种替代方法是使用 Area2D
而不是 RayCast2D
.其优点是拥有自己的 CollisionShape2D
或 CollisionPolygon2D
.您将需要保持进入或存在 Area2D
的机构的数量:
Another alternative is to use an Area2D
instead of a RayCast2D
. Which has the advantage of having its own CollisionShape2D
or CollisionPolygon2D
. You will need to keep count of bodies that enter or exist the 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
当然,在你的支票中使用它来跳转:
And of course, use that in your check to jump:
if Input.is_action_just_released("ui_up") and on_ground > 0:
apply_central_impulse(Vector2(0,-1000))
最后我提醒你,你有碰撞层和碰撞蒙版.使用 RayCast2D
或 Area2D
将允许您设置与 RigidBody2D
使用的掩码不同的掩码.这是一种指定不是所有 RigidBody2D
碰撞的东西都是它可以跳跃的东西的方法.
Finally I remind you that you have collision layers and collision masks. Using a RayCast2D
or an Area2D
would allow you to set a different mask than the one the RigidBody2D
uses. Which is a way to specify that not all things that the RigidBody2D
collides with, are things from which it can jump.
我发现 Area2D
更加可靠和通用.但是,设置工作量更大.
I find Area2D
to be more reliable and versatile. However, it is more work to setup.
这篇关于我怎样才能让刚体在 godot 中跳跃而不赋予它飞行的能力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!