on_body_entered 和 on_body_exited 的 Godot 奇怪行为

Godot odd behavior with on_body_entered and on_body_exited

我有一个 KinematicBody2D(玩家)和一个 Area2D(梯子)。使用下面的代码,我得到了干净的进入和退出事件,这些事件发生在玩家触摸和离开 Area2D 对象时,例如触摸 Area2D 并打印一个“输入”。向后移动并打印一个“exit”。

func _on_Ladder_body_entered(body):
    if body.name == "Hero":
        print("enter")

func _on_Ladder_body_exited(body):
    if body.name == "Hero":
        print("exit")

这段代码出错了:

func _on_Ladder_body_entered(body):
    if body.name == "Hero":
        set_collision_layer_bit(0, false)
        print("enter")

func _on_Ladder_body_exited(body):
    if body.name == "Hero":
        set_collision_layer_bit(0, true)
        print("exit")

一旦玩家接触到 Area2D,我就会立即收到进入事件和退出事件。我究竟做错了什么?谢谢! Godot 版本 3.4.2

Godot 正在按照您的指示进行操作。

调用 set_collision_layer_bit(0, false) 将禁用 KinematicBody2DArea2D 之间的碰撞,这意味着它们将不再发生碰撞。由于它们停止碰撞,您会收到 "body_exited" 信号。


I want to turn off collisions so the player can pass the object and re-enable them when he passes and leaves the Area2D object

Area2D不停止物理体(StaticBody2DKinematicBody2DRigidBody)。一定有别的东西在做那件事。例如,如果你在梯子上添加了一个 StaticBody2D,或者用 TileMap 制作了一个 TileMap ,那里的瓷砖有碰撞,这些可能会阻止你的 KinematicBody2D.


我认为最简单的方法是将 Area2D 放在不同的碰撞层中,这样您就可以在不禁用 Area2D 的情况下禁用停止 KinematicBody2D 的碰撞。

其他禁用碰撞的选项包括:

  • 通过将 disabled 设置为 true 来禁用 CollisionPolygon2DCollisionShape2D。注意:当 Godot 正在解决碰撞响应时,你不能这样做。为避免这种情况,请使用 set_deferred 更改 disabled.
  • 的值
  • 通过调用 add_collision_exception_with 添加碰撞异常。使用 remove_collision_exception_with 删除异常。这是一个更细粒度的工具,应该谨慎使用(如果你要添加很多例外,更喜欢使用碰撞层和遮罩)。

附录TileMap 的一个选项是有两个版本的图块,一个有碰撞,一个没有。并在运行时用 set_cell 交换它们。但是,请考虑改用场景。事实上,您可能希望在设计器中设置单元格,并在运行时用实际场景替换它们。见 How to use SCENES in a TILEMAP(And 9 MORE TRICKS) | Godot Engine. You may even do it only when the player gets nearby, see How to create large Sidescrolling Map in Godot?.