How do I stop player from moving when he is attacking ?

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

hi, so I’m a little stumped on how to prevent the player character from moving when attacking. my goal is to make it so that the player stands still until the attack animation stops and then the player can proceed to move freely again. but right now if you hold a directional input like left or right the player will perform the attack animation and slide across the floor. you can see why this is not great. right now this is my code just in case someone can point out something I overlooked.

extends KinematicBody2D

"PLAYER CHARACTER CONTROLS"

const UP = Vector2(0,-1)
const GRAVITY = 35
const VELOCITY = 20

var motion = Vector2(0,0)
var walk_speed =Vector2(400,0)
var jump_height = Vector2(0,-900)
var jump_forward = Vector2(-400,-900)
var jump_backward = Vector2(400,-900)
var state_machine 
func _ready():
	    state_machine = get_node("AnimatedSprite/AnimationPlayer/AnimationTree").get("parameters/playback")

func _physics_process(delta):
	motion.y += GRAVITY
	motion = move_and_slide(motion,UP)
	if is_on_floor():
		motion.y = 0
		motion.x = 0
		walk()
		idle()
		crouch()
		jump()
		attack_stand_punches()
		attack_low_kicks()
		attack_air_punches()

func walk():
		if Input.is_action_pressed("ui_left"):
			motion = -walk_speed
			state_machine.travel("Walk Forward")
		if Input.is_action_pressed("ui_right"):
			motion = walk_speed
			state_machine.travel("Walk Backwards")

func idle():
		if motion == Vector2(0,0):
			state_machine.travel("default")

func crouch():
	if is_on_floor():
		if Input.is_action_pressed("ui_down"):
			state_machine.travel("Crouching idle")
			motion.x = 0
		elif Input.is_action_just_released("ui_down"):
			idle()
		
func jump():
	if Input.is_action_just_pressed("ui_up"):
		motion = jump_height
		state_machine.travel("Jump")
		if Input.is_action_pressed("ui_left"):
			state_machine.travel("Jump forward")
			motion = jump_forward
		elif Input.is_action_pressed("ui_right"):
			state_machine.travel("Jump backwards")
			motion = jump_backward

func attack_stand_punches():
	
	if Input.is_action_pressed("ui_down") == false:
		if Input.is_action_just_pressed("Mid Punch"):
			state_machine.travel("mid punch")
			motion.x = 0
			attack_ground_movement_stop()
func attack_low_kicks():
	if Input.is_action_pressed("ui_down"):
		if Input.is_action_just_pressed("Mid Kick"):
			state_machine.travel("low mid kick")
func attack_air_punches():
	if _is_on_air():
		if Input.is_action_just_pressed("Mid Punch"):
			state_machine.travel("air punch")

Any help is greatly appreciated.

:bust_in_silhouette: Reply From: Christiaan

One way would be to add a variable to check if your character is attacking and set it to true when you press the attack button. And don’t allow the player to move when attacking.

:bust_in_silhouette: Reply From: klaas

Hi,
you have to observe your animationPlayer. Either with connecting the signals or with AnimationPlayer.is_playing() method.

connect the signal

func _ready():
        state_machine = get_node("AnimatedSprite/AnimationPlayer/AnimationTree").get("parameters/playback")
       state_machine.connect("animation_finished",self,"_on_animation_finished")

create a callback to process the finished anims

func _on_animation_finished(anim_name):
   match anim_name:
      "mid punch":
         is_attacking = false

make avariable to save attack state

func attack_stand_punches():
    if Input.is_action_pressed("ui_down") == false:
        if Input.is_action_just_pressed("Mid Punch"):
            state_machine.travel("mid punch")
            is_attacking = true #<------
            motion.x = 0
            attack_ground_movement_stop()
func attack_low_kicks():
    if Input.is_action_pressed("ui_down"):
        if Input.is_action_just_pressed("Mid Kick"):
            is_attacking = true #<------
            state_machine.travel("low mid kick")
func attack_air_punches():
    if _is_on_air():
        if Input.is_action_just_pressed("Mid Punch"):
            is_attacking = true #<------
            state_machine.travel("air punch")

stop movement when attacking

func _physics_process(delta):
    if is_attacking:
        return
    motion.y += GRAVITY
    motion = move_and_slide(motion,UP)
    if is_on_floor():

Did not test it

wait so does the signal for
func _on_animation_finished(anim_name):
come from the AnimatedSprite Node or the Animationplayer Node.

also, I don’t really know how the .is_playing() method works exactly, whenever I use it the game would always crash for some reason in my earlier builds. I’m pretty sure it was just my inexperience but any help is welcomed

Aby_is_a_kitkat | 2020-07-23 04:03

the signal comes from the animationPlayer

AnimationPlayer — Godot Engine (stable) documentation in English

the is_playing() returns true if an animation is playing

AnimationPlayer — Godot Engine (stable) documentation in English

klaas | 2020-07-23 09:23