Reputation: 23
I am trying to make a simple game in Godot where a wall falls down and the player has to dodge it. The wall is a RigidBody2D with a sprite and CollisionShape2D attached. The player is a KinematicBody2D with a sprite and CollisionShape2D attached. The main scene is a Node2D with the player and wall as children of it. I have managed to get the player to detect collisions but when I emit a signal (which is connected to the wall script), the wall does nothing. I have already tried using the body_entered
signal in the player script, but nothing happens. Does anybody know how to fix this?
My player script:
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()
The wall script:
extends RigidBody2D
func _on_Player_game_over():
print("player collided") #example to see if collision is detected
Upvotes: 2
Views: 3121
Reputation: 40220
I can't tell why your code is not working. However, I would do it differently: Instead of emitting a signal, call a method on the collider
:
if collision.collider.is_in_group("Level"):
collision.collider._on_Player_game_over()
death()
It is probably worth giving the method a better name.
By the way, you can also check if the collider has the method. For example:
if collision.collider.has_method("_on_Player_game_over"):
collision.collider._on_Player_game_over()
death()
The rest of this answer is explaining how to handle the collision on the RigidBody2D
with the "body_entered"
signal.
First make sure the RigidBody2D
has contact_monitor
set to true
.
Also set its contacts_reported
to a value greater than 0
. There can be multiple contacts with the same body, and you need to consider possible contacts with other bodies. A value around 8
is probably OK.
Have the "body_entered"
signal of the RigidBody2D
connected to itself.
in the method in the RigidBody2D
that handles the "body_entered"
signal you would get a body
parameter:
func _on_Wall_body_enter(body):
print("Collision")
By the way, I would like to encourage to take advantage of collision layer and masks. So you can narrow what collisions the RigidBody2D
even checks for.
Then you can filter what body it is. You can, for example:
Use the name:
func _on_Wall_body_enter(body):
if body.name == "Player":
print("Collision with player")
Use a group:
func _on_Wall_body_enter(body):
if body.is_in_group("Player"):
print("Collision with player")
Use a class name (this requires to add a class_name
to the player):
func _on_Wall_body_enter(body):
if body is Player:
print("Collision with player")
Check for a method:
func _on_Wall_body_enter(body):
if body.has_method("death"):
print("Collision with player")
And, of course, you can call a method on it notify. For example:
func _on_Wall_body_enter(body):
if body is Player:
body.death()
Or
func _on_Wall_body_enter(body):
if body.has_method("death"):
body.death()
Upvotes: 3