Heartbeast's Action RPG improvement on player's knockback.

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

So I just finished Heartbeast’s Action rpg tutorial video and I decided to add some features on my own. one of it is the knockback of the player that got hit by the enemy. so I used this code.

var hitKnockBack = Vector2.ZERO

for the player hit knock back force, and then for the move state I changed it as following:

		func move_state(delta):
var input_vector = Vector2.ZERO
input_vector.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left");
input_vector.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up");
input_vector = input_vector.normalized()

if input_vector != Vector2.ZERO:
	roll_vector = input_vector
	swordHitbox.knockback_vector = input_vector
	animationTree.set("parameters/idle/blend_position", input_vector)
	animationTree.set("parameters/Run/blend_position", input_vector)
	animationTree.set("parameters/Attack/blend_position", input_vector)
	animationTree.set("parameters/Roll/blend_position", input_vector)
	animationState.travel("Run")
	velocity = velocity.move_toward(input_vector * MAX_SPEED, ACCELERATION * delta)
else:
	animationState.travel("idle")
	velocity = velocity.move_toward(Vector2.ZERO, FRICTION * delta)
hitKnockBack = hitKnockBack.move_toward(Vector2.ZERO, 500 * delta)
hitKnockBack = move_and_slide(hitKnockBack)
move(delta)

if Input.is_action_just_pressed("roll"):
	state = ROLL

if Input.is_action_just_pressed("attack"):
	state = ATTACK

then when player’s hurtbox got entered by the bat I take the area that entered the player’s hurtbox which is the bat’s hitbox then I take the parent which is the bat’s kinematicbody2D and take the velocity of it and assign it to player’s hitKnockBack like this:

func _on_Hurtbox_area_entered(area):
stats.health -= area.damage
hurtBox.start_invincibility(1)
hurtBox.create_hit_effect()
hitKnockBack = area.get_parent().velocity * 6
var playerHurtSound = PLAYERHURTSOUND.instance()
get_tree().current_scene.add_child(playerHurtSound)

now I tested this one and it works. but I want to know if there’s a better way of doing this? because the multiplier 6 there seems too random for me but that’s what works for me. if I put something like 500 or even 10 it seems that the knockback force will be too massive.

this is how the bat codes look:

export var accelerator = 70
export var max_speed = 20
export var friction = 500
export var wander_target_range = 8
 func accelerate_towards_point(position, delta):
    var direction = global_position.direction_to(position)
	velocity = velocity.move_toward(direction*max_speed, accelerator*delta)
	sprite.flip_h = velocity.x < 0

so is there any other way I can do the player knockback better?

You think look https://esreva.com

esrevacom | 2023-04-28 19:06

:bust_in_silhouette: Reply From: TRAILtheGREAT

This looks like a pretty reasonable implementation. It works, and that’s what matters.

On the topic of the number 6, I think that behavior is inherent to the way math works. You’re instantaneously setting the velocity of the player and then decelerating them at a constant rate. So if you set their velocity to be twice as fast, it will take twice the amount of time for you to reduce their velocity back to zero, and because they are moving so much faster immediately after they are knocked back, they travel much further in those first few fractions of a second. (I want to say it would travel 4 times as far? someone can correct me though.)