如何检测 Godot 中的 KinematicBody2D 和 RigidBody2D 之间的碰撞?
How do I detect collisions between a KinematicBody2D and a RigidBody2D in Godot?
我正在尝试在 Godot 中制作一个简单的游戏,其中一堵墙倒塌,玩家必须躲避它。墙是一个附有 sprite 和 CollisionShape2D 的 RigidBody2D。播放器是一个带有精灵和 CollisionShape2D 的 KinematicBody2D。主场景是一个 Node2D,播放器和墙是它的 children。我已经设法让播放器检测到碰撞,但是当我发出信号(连接到墙脚本)时,墙什么都不做。我已经尝试在播放器脚本中使用 body_entered
信号,但没有任何反应。有人知道如何解决这个问题吗?
我的播放器脚本:
extends KinematicBody2D
var speed = 1300
var velocity = Vector2()
signal game_over
func get_input():
velocity = Vector2()
if Input.is_action_pressed('d'):
velocity.x += 1
if Input.is_action_pressed('a'):
velocity.x -= 1
velocity = velocity.normalized() * speed
func _physics_process(delta):
get_input()
move_and_slide(velocity, Vector2(0, 0), false, 4, 0.785, false)
for index in get_slide_count():
var collision = get_slide_collision(index)
if collision.collider.is_in_group("Level"):
death()
func death():
emit_signal("game_over")
hide()
壁画:
extends RigidBody2D
func _on_Player_game_over():
print("player collided") #example to see if collision is detected
我不知道为什么你的代码不起作用。但是,我会做不同的事情:不是发出信号,而是在 collider
:
上调用一个方法
if collision.collider.is_in_group("Level"):
collision.collider._on_Player_game_over()
death()
可能值得为该方法起一个更好的名称。
对了,你也可以看看collider有没有这个方法。例如:
if collision.collider.has_method("_on_Player_game_over"):
collision.collider._on_Player_game_over()
death()
这个答案的其余部分解释了如何处理 RigidBody2D
与 "body_entered"
信号的冲突。
首先确保 RigidBody2D
已将 contact_monitor
设置为 true
。
同时将其 contacts_reported
设置为大于 0
的值。同一个 body 可以有多个联系人,您需要考虑与其他机构的可能联系人。 8
左右的值可能没问题。
将 RigidBody2D
的 "body_entered"
信号 连接到自身 。
在 RigidBody2D
中处理 "body_entered"
信号的方法中你会得到一个 body
参数:
func _on_Wall_body_enter(body):
print("Collision")
顺便提一下,我鼓励大家利用碰撞层和遮罩。因此,您可以缩小 RigidBody2D
甚至检查的碰撞范围。
然后你可以过滤body是什么。例如,您可以:
使用姓名:
func _on_Wall_body_enter(body):
if body.name == "Player":
print("Collision with player")
使用群组:
func _on_Wall_body_enter(body):
if body.is_in_group("Player"):
print("Collision with player")
使用class名称(这需要给播放器添加class_name
):
func _on_Wall_body_enter(body):
if body is Player:
print("Collision with player")
检查方法:
func _on_Wall_body_enter(body):
if body.has_method("death"):
print("Collision with player")
当然,你可以在它上面调用一个方法notify。例如:
func _on_Wall_body_enter(body):
if body is Player:
body.death()
或
func _on_Wall_body_enter(body):
if body.has_method("death"):
body.death()
我正在尝试在 Godot 中制作一个简单的游戏,其中一堵墙倒塌,玩家必须躲避它。墙是一个附有 sprite 和 CollisionShape2D 的 RigidBody2D。播放器是一个带有精灵和 CollisionShape2D 的 KinematicBody2D。主场景是一个 Node2D,播放器和墙是它的 children。我已经设法让播放器检测到碰撞,但是当我发出信号(连接到墙脚本)时,墙什么都不做。我已经尝试在播放器脚本中使用 body_entered
信号,但没有任何反应。有人知道如何解决这个问题吗?
我的播放器脚本:
extends KinematicBody2D
var speed = 1300
var velocity = Vector2()
signal game_over
func get_input():
velocity = Vector2()
if Input.is_action_pressed('d'):
velocity.x += 1
if Input.is_action_pressed('a'):
velocity.x -= 1
velocity = velocity.normalized() * speed
func _physics_process(delta):
get_input()
move_and_slide(velocity, Vector2(0, 0), false, 4, 0.785, false)
for index in get_slide_count():
var collision = get_slide_collision(index)
if collision.collider.is_in_group("Level"):
death()
func death():
emit_signal("game_over")
hide()
壁画:
extends RigidBody2D
func _on_Player_game_over():
print("player collided") #example to see if collision is detected
我不知道为什么你的代码不起作用。但是,我会做不同的事情:不是发出信号,而是在 collider
:
if collision.collider.is_in_group("Level"):
collision.collider._on_Player_game_over()
death()
可能值得为该方法起一个更好的名称。
对了,你也可以看看collider有没有这个方法。例如:
if collision.collider.has_method("_on_Player_game_over"):
collision.collider._on_Player_game_over()
death()
这个答案的其余部分解释了如何处理 RigidBody2D
与 "body_entered"
信号的冲突。
首先确保
RigidBody2D
已将contact_monitor
设置为true
。同时将其
contacts_reported
设置为大于0
的值。同一个 body 可以有多个联系人,您需要考虑与其他机构的可能联系人。8
左右的值可能没问题。将
RigidBody2D
的"body_entered"
信号 连接到自身 。在
RigidBody2D
中处理"body_entered"
信号的方法中你会得到一个body
参数:func _on_Wall_body_enter(body): print("Collision")
顺便提一下,我鼓励大家利用碰撞层和遮罩。因此,您可以缩小
RigidBody2D
甚至检查的碰撞范围。然后你可以过滤body是什么。例如,您可以:
使用姓名:
func _on_Wall_body_enter(body): if body.name == "Player": print("Collision with player")
使用群组:
func _on_Wall_body_enter(body): if body.is_in_group("Player"): print("Collision with player")
使用class名称(这需要给播放器添加
class_name
):func _on_Wall_body_enter(body): if body is Player: print("Collision with player")
检查方法:
func _on_Wall_body_enter(body): if body.has_method("death"): print("Collision with player")
当然,你可以在它上面调用一个方法notify。例如:
func _on_Wall_body_enter(body): if body is Player: body.death()
或
func _on_Wall_body_enter(body): if body.has_method("death"): body.death()