Godot Version
4.7
Question
Hi everyone! I’m trying to set up clean movement for my enemies in Godot 4, but I’m getting stuck trying to combine a few different behaviors:
Regular Movement / Lunging: Getting the enemy to move toward the player or lunge at them to attack.
Knockback: Pushing the enemy backward smoothly when they take damage instead of sliding or glitching.
Whenever I try to mix these together, they fight each other or don’t feel smooth. How should I structure my code so movement, lunging, and knockback work nicely together?
Here is what I have tried so far for the player code:
extends CharacterBody2D
signal check_flip_h
var is_attacking = false
signal check_flip_h_1
signal keep_it_stable
signal copy_player_direction_tree_spider_left
signal copy_player_direction_tree_spider_right
signal slash_began
signal slash_finished
signal slash_began1
var cut_jump_hight = 0.01
signal slash_finished1
var roll = 0
var go_left = Input.is_action_just_pressed(“go left”)
signal sound_play
var i_have_the_demon_sword = false
var yafa_slash = false
var SPEED = 250
var JUMP_VELOCITY = -400.0
func _physics_process(delta: float) → void:
if Input.is_action_just_released("jump") and velocity.y < 0:
velocity.y \*= cut_jump_hight
if yafa_slash == true:
move_and_slide()
return
if Input.is_action_just_pressed("jump") and is_on_floor():
$"2".play()
if not is_on_floor():
velocity += get_gravity() \* delta
\# Handle jump.
if Input.is_action_just_pressed("jump") and is_on_floor():
velocity.y = JUMP_VELOCITY
var direction := Input.get_axis("go left", "go right")
if direction:
velocity.x = direction \* SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
if $idle.flip_h == true:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = true
if $idle.flip_h == false:
$"sword hold idle right".visible = true
$"sword hold idle left".visible = false
if yafa_slash == false:
if direction == 0:
$AnimationPlayer.play("idle")
$run.visible = false
$idle.visible = true
$jump.visible = false
$"yafa sword slash 1".visible = false
$"yafa sword slash 11".visible = false
if i_have_the_demon_sword == true:
if $idle.flip_h == true:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = true
if $idle.flip_h == false:
$"sword hold idle right".visible = true
$"sword hold idle left".visible = false
if i_have_the_demon_sword == false:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = false
if direction != 0:
$AnimationPlayer.play("run1")
$idle.visible = false
$run.visible = true
$jump.visible = false
$"yafa sword slash 1".visible = false
$"yafa sword slash 11".visible = false
if i_have_the_demon_sword == true:
if $idle.flip_h == true:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = true
if $idle.flip_h == false:
$"sword hold idle right".visible = true
$"sword hold idle left".visible = false
if i_have_the_demon_sword == false:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = false
if not is_on_floor():
$AnimationPlayer.play("jump")
$jump.visible = true
$run.visible = false
$idle.visible = false
$"yafa sword slash 1".visible = false
$"yafa sword slash 11".visible = false
if i_have_the_demon_sword == true:
if $idle.flip_h == true:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = true
if $idle.flip_h == false:
$"sword hold idle right".visible = true
$"sword hold idle left".visible = false
if i_have_the_demon_sword == false:
$"sword hold idle right".visible = false
$"sword hold idle left".visible = false
if direction <0:
copy_player_direction_tree_spider_left.emit()
if direction >0:
copy_player_direction_tree_spider_right.emit()
if direction <0:
$run.flip_h = true
if direction >0:
$run.flip_h = false
if direction <0:
$idle.flip_h = true
if direction >0:
$idle.flip_h = false
if direction <0:
$jump.flip_h = true
if direction >0:
$jump.flip_h = false
if direction <0:
$"yafa sword slash 1".flip_h = true
if direction >0:
$"yafa sword slash 1".flip_h = false
if direction <0:
$"yafa sword slash 11".flip_h = true
if direction >0:
$"yafa sword slash 11".flip_h = false
if i_have_the_demon_sword == true:
if Input.is_action_just_pressed("yafa slash 1"):
check_flip_h.emit()
check_flip_h_1.emit()
func _on_demon_sword_item_yafa_you_tooke_the_demon_sowrd() → void:
i_have_the_demon_sword = true
sound_play.emit()
func _on_yafa_sword_slash_1_yes_it_is() → void:
$"demon swrod attttack sound effect".play()
if is_attacking == false:
is_attacking = true
$AnimationPlayer.play("yafa sword slash 1")
slash_began1.emit()
yafa_slash = true
$jump.visible = false
$run.visible = false
$idle.visible = false
$"yafa sword slash 1".visible = true
$"sword hold idle right".visible = false
$"sword hold idle left".visible = false
await $AnimationPlayer.animation_finished
is_attacking = false
slash_finished1.emit()
yafa_slash = false
func _on_yafa_sword_slash_11_yes_it_is_11() → void:
$"demon swrod attttack sound effect".play()
if is_attacking == false:
is_attacking = true
$AnimationPlayer.play("yafa sword slash 1.1")
slash_began.emit()
yafa_slash = true
$jump.visible = false
$run.visible = false
$idle.visible = false
$"yafa sword slash 1".visible = false
$"yafa sword slash 11".visible = true
$"sword hold idle right".visible = false
$"sword hold idle left".visible = false
await $AnimationPlayer.animation_finished
is_attacking = false
slash_finished.emit()
yafa_slash = false
if Input.is_action_just_pressed("go left"):
pass
if Input.is_action_just_pressed("go right"):
pass
func _on_left_go_left() → void:
print("i am sup")
And here is waht i have so far in the enymy code:
extends CharacterBody2D
signal disable_collisons
signal disable_the_attack
var cool_down = false
var is_attacking = false
var dead = false
var health = 50
var SPEED = 300.0
var JUMP_VELOCITY = -400.0
var do_noises = true
var knockback_velocity: Vector2 = Vector2.ZERO
func _physics_process(delta: float) → void:
if dead == false:
if is_attacking == false:
if velocity.x == 0:
$"nature taken knight shape".visible = true
$"nature taken knight shape 2".visible = false
$"green shoooooooot".visible = false
$"green shoot other side".visible = false
$"AnimationPlayer of nature taken knight".play("nature taken knight idle animation")
$head.visible = false
$"left hand".visible = false
$"right hand".visible = false
$tourso.visible = false
if velocity.x != 0:
pass
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
move_and_slide()
func _on_left_attack_get_ddemge() → void:
health -= 10
$"robot geting damged".play()
$"nature taken knight shape".visible = false
$"nature taken knight shape 2".visible = false
$"green shoooooooot".visible = false
$"green shoot other side".visible = false
$head.visible = true
$"left hand".visible = true
$"right hand".visible = true
$tourso.visible = true
$"AnimationPlayer of nature taken knight".play("damged")
if health <= 0:
dead = true
print("dead")
$"nature taken knight shape".visible = false
$"nature taken knight shape 2".visible = false
$"green shoooooooot".visible = false
$"green shoot other side".visible = false
$head.visible = true
$"left hand".visible = true
$"right hand".visible = true
$tourso.visible = true
$"AnimationPlayer of nature taken knight".play("deathy after")
disable_collisons.emit()
$"nature taken knight noises".stop()
func _on_right_attack_get_damged() → void:
health -= 10
$"robot geting damged".play()
$"nature taken knight shape".visible = false
$"nature taken knight shape 2".visible = false
$head.visible = true
$"left hand".visible = true
$"right hand".visible = true
$tourso.visible = true
$"AnimationPlayer of nature taken knight".play("damged")
if health <= 0:
dead = true
print("dead")
$"nature taken knight shape".visible = false
$"nature taken knight shape 2".visible = false
$head.visible = true
$"left hand".visible = true
$"right hand".visible = true
$tourso.visible = true
$"AnimationPlayer of nature taken knight".play("deathy after")
disable_collisons.emit()
$"nature taken knight noises".stop()
func _on_left_go_left() → void:
is_attacking = true
$head.visible = false
$"left hand".visible = false
$"right hand".visible = false
$tourso.visible = false
$"nature taken knight shape".visible = false
$"nature taken knight shape 2".visible = false
$"green shoooooooot".visible = false
$"green shoot other side".visible = true
$"AnimationPlayer of nature taken knight".play("green shot animation lft other side")
await get_tree().create_timer(0.3).timeout
is_attacking = false
func _on_right_play_right() → void:
is_attacking = true
$head.visible = false
$"left hand".visible = false
$"right hand".visible = false
$tourso.visible = false
$"nature taken knight shape".visible = false
$"nature taken knight shape 2".visible = false
$"green shoooooooot".visible = true
$"green shoot other side".visible = false
$"AnimationPlayer of nature taken knight".play("green shhhot animaiton")
await get_tree().create_timer(0.3).timeout
is_attacking = false
And pleas when you help me explain how these codes work i menat hte codes that you will send me. THANK YOU!