中跳跃而不赋予它飞行的能力

中跳跃而不赋予它飞行的能力

本文介绍了我怎样才能让刚体在 godot 中跳跃而不赋予它飞行的能力的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我会使用运动学身体,但我想为我的 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 代替.将其定位为从 RigidBody2DCollisionShape2DCollisionPolygon2D 的底部向下延伸.确保 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.其优点是拥有自己的 CollisionShape2DCollisionPolygon2D.您将需要保持进入或存在 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))


最后我提醒你,你有碰撞层和碰撞蒙版.使用 RayCast2DArea2D 将允许您设置与 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 中跳跃而不赋予它飞行的能力的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 13:02