Search code examples
godotgdscriptgodot4

My tutorial code to knockback an enemy does not work because of move_toward


I was watching a tutorial and I followed the code the same as in the video, but the tutorial is for godot 3.2 and being on godot 4 it does not work when attacking the enemy and I get an error that says: Invalid call. Nonexistent function 'move_toward' in base 'bool'. This is the code:

extends CharacterBody2D

var knockback = Vector2.ZERO

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

func _on_hurtbox_area_entered(area):
    knockback = Vector2.RIGHT * 200

I tried to delete the move_and_slide arguments and tried to change the move_toward to move_and_slide but it doesn't work


Solution

  • What is happening is that move_and_slide returns bool (true if it collided, false if it didn't).

    Thus, here:

    knockback = move_and_slide()
    

    The knockback variable becomes a bool. Thus, next frame, when you try to do this:

    knockback = knockback.move_toward(Vector2.ZERO, 200 * delta)
    

    Godot can't call move_toward on a bool, and give you an error.


    You would have gotten the error earlier if you make knockback a typed variable, which would be explicitly like this:

    var knockback:Vector2 = Vector2.ZERO
    

    Or implicitly (with inference) like this:

    var knockback:= Vector2.ZERO
    

    Furthermore, as you know, in Godot 4 move_and_slide no longer takes a velocity, instead you are supposed to set the velocity property. Which means, you could make away with not having a knockback variable.

    The code would be like this:

    extends CharacterBody2D
    
    func _physics_process(delta):
        velocity = velocity.move_toward(Vector2.ZERO, 200 * delta)
        move_and_slide()
    
    func _on_hurtbox_area_entered(area):
        velocity += Vector2.RIGHT * 200
    

    Here the line using move_toward is performing deceleration.

    Presumably you will have other code manipulating velocity, thus double check if you are not doing deceleration already (in which case you do not need to do it here), and if adding deceleration do not mess with anything else.