• Godot Help
  • Need sliding object to kill enemies, is bouncing off of them instead

Hello,

I've been following a series of tutorials on YouTube (BornCG 2D Platformer). I have an object that gets kicked by the player and should kill any enemies it slides into. It currently detects the enemies and bounces off of them. I am basically using the same functionality as a fireball in which a side checker should detect a hit and then queue free on it. As far as I know I have the collision layer and masks set correctly. I'm not sure what I'm doing wrong. Hopefully I've posted everything needed to figure out why it's not working. Please let me know if you need any further information. Thank you!!!

SLIDING OBJECT CODE:

extends KinematicBody2D

var speed = 400
var velocity = Vector2(100,0)
export var direction = -1
var collision = KinematicCollision2D
var shells = false
export var detects_cliffs = true

func _ready():
	if direction == 1:
		$AnimatedSprite.flip_h = true
	$floor_checker.position.x = $CollisionShape2D.shape.get_extents().x * direction
	$floor_checker.enabled = detects_cliffs
	
func _physics_process(delta:float)-> void:
	if shells:
		if is_on_wall() or not $floor_checker.is_colliding() and detects_cliffs and is_on_floor():
			direction = direction * -1
			$AnimatedSprite.flip_h = not $AnimatedSprite.flip_h
			$floor_checker.position.x = $CollisionShape2D.shape.get_extents().x * direction
			
		velocity.y += 20
		
		velocity.x = speed * direction
	
		velocity = move_and_slide(velocity,Vector2.UP)
		
		
func _on_sides_checker_body_entered(body):
	velocity.x = speed * direction
	if shells == false:
		shells = true
	
	#if body.get_collision_layer() == 1:
		#body.ouch(position.x)
	#elif body.get_collision_layer() == 16:
		#body.queue_free()
	#elif body.get_collision_layer() == 32:
		#body.queue_free()
		#queue_free()

func _on_top_checker_body_entered(body):
	velocity.x = speed * direction
	
	if shells:
		if body.get_collision_layer() == 1:
			body.ouch(position.x)
		elif body.get_collision_layer() == 32:
			body.queue_free()
			queue_free()
		
	if shells == false:
		shells = true

OBJECT COLLISION:

ENEMY CODE:

extends KinematicBody2D

var speed = 50
var velocity = Vector2()
var enemy
export var direction = -1
export var detects_cliffs = true

func _ready():
	if direction == 1:
		$AnimatedSprite.flip_h = true
	$floor_checker.position.x = $CollisionShape2D.shape.get_extents().x * direction
	$floor_checker.enabled = detects_cliffs
	if detects_cliffs:
		set_modulate(Color(.8,0.8,0.8))

func _physics_process(delta):
	
	if is_on_wall() or not $floor_checker.is_colliding() and detects_cliffs and is_on_floor():
		direction = direction * -1
		$AnimatedSprite.flip_h = not $AnimatedSprite.flip_h
		$floor_checker.position.x = $CollisionShape2D.shape.get_extents().x * direction
	
	velocity.y += 20
	
	velocity.x = speed * direction
	
	velocity = move_and_slide(velocity,Vector2.UP)





func _on_top_checker_body_entered(body):
	$AnimatedSprite.play("squash")
	$SoundSquash.play()
	speed = 0
	set_collision_layer_bit(4,false)
	set_collision_mask_bit(0,false)
	$top_checker.set_collision_layer_bit(4,false)
	$top_checker.set_collision_mask_bit(0,false)
	$sides_checker.set_collision_layer_bit(4,false)
	$sides_checker.set_collision_mask_bit(0,false)
	$Timer.start()
	body.bounce()
	
	



func _on_sides_checker_body_entered(body):
	if body.get_collision_layer() == 1:
		body.ouch(position.x)
	elif body.get_collision_layer() == 32:
		body.queue_free()
		queue_free()
	#$SoundDie.play()


func _on_Timer_timeout():
	queue_free()

ENEMY COLLISION:

The collision layers/masks in the images look correct for detecting collisions. But my understanding is that you can't detect collisions between KinematicBody2D's. If you can't change the node types, what might work is to add an Area2D as a child to one of them, and use its area_entered signal to detect when they collide.

Hi Dave,

Thanks very much for your response! I believe I have an area 2D node on both objects already. I have added this function to the Goomba which should detect the shell. I see that monitoring needs to be set to "true" but I have not yet found how to do that. Not sure if these screenshots help at all but just throwing them in here so you can see my nodes. I know this is copyrighted stuff but not to worry it's purely for learning and is never going to be published anywhere other than my own personal computer.

If I understand correctly I have monitoring enabled correctly:

But then it doesn't like this code:

I'm looking at the Godot documentation but so far I've not been able to figure this out.

Thanks again!

    seanb Can I have an Area2D in tandem with a CollisionShape2D?

    An Area2D can have a CollisionShape2D as a child, and use that to detect collisions.
    There's an example here ("Hiding and showing the roof"):
    https://www.davidepesce.com/2020/03/10/godot-tutorial-18-adding-house-with-interior/

    seanb I just need to figure out how to set monitoring to true.

    "monitoring" is a property of an Area2D. You can set it in code or in the Inspector. But I think it defaults to "true".

      DaveTheCoder

      Hi Dave,

      I actually figured it out thanks to you! Didn't realize it was this simple: