Knockback Issue (HeartBeast Tutorial)

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Kinross07

So like many before me I’ve been following and playing along with HeartBeast’s Action RPG tutorial. I’m still pretty new to scripting in general so trying to understand why things aren’t working before moving on to the next step and hoping I can fix it later.

Things that I know are different between my code and his:

  • Addition of $Sprite.play because otherwise it never animated
  • move_and_slide() changed so it should just be its own line
  • queue_free() present just for confirming that the hitbox detection works (it does) and layers are correct
  • _process instead of _physics_process - another user said this worked for them, but no difference either way.

Bat Code:

extends CharacterBody2D

var knockback = Vector2.ZERO

func _ready():
    $Sprite.play("Fly")

func _process(delta):
	knockback = knockback.move_toward(Vector2.ZERO, 200 * delta)
	move_and_slide()

func _on_hurtbox_area_entered(area):
    knockback = area.knockback_vector * 120
    queue_free()

For completeness, here is the sword hitbox code:

extends Area2D

var knockback_vector = Vector2.ZERO

Happy to provide more information where I can.

:bust_in_silhouette: Reply From: PolyBytes

If your issue is that the knockback isn’t working it is because your knockback_vector is Vector2.ZERO so no matter what you multiply it by it will still be (0, 0). You are also immediately calling queue_free() on the Bat so you really wouldn’t even see any knockback anyway.

If it were me in this case I would remove the knockback_vector. Then, on the Bat scene make a Timer node and call it DespawnTimer or whatever suits you. Set the delay on the timer to be around like 0.5 seconds and enable the One Shot tick box. After this you should connect the timeout() signal to your Bat code.

Then what you would probably want to do is something along the lines of this in the Bat code:

extends CharacterBody2D

@export var knockback_power: float = 120.0
@export var slowdown_speed: float = 200.0

@onready var despawn_timer: Timer = $DespawnTimer

func _ready():
    $Sprite.play("Fly")

func _physics_process(delta):
    velocity = velocity.move_toward(Vector2.ZERO, slowdown_speed * delta)
    move_and_slide()

func _on_hurtbox_area_entered(area):
    velocity = area.global_position.direction_to(self.global_position) * knockback_power
    despawn_timer.start()

func _on_DespawnTimer_timeout():
    queue_free()

Also I typed this on my phone so if there are any issues or if you have any questions just let me know!

Thank you so much for the help, in typical fashion worked out a fix myself at the same time xD

I will leave it be for now until I reach the end, but will definitely bear this in mind once I start fiddling with things a bit more :slight_smile:

Kinross07 | 2023-04-30 13:18

:bust_in_silhouette: Reply From: Kinross07

Hit my head against the wall a bit more and eventually found the issue.

_process needed to include

velocity = knockback

but weirdly when I did this at the time it got very upset at me about inheriting from CharacterBody2D, so assumed it was defunct code.