Reputation: 13
How do I prevent player to not move when it is attacking? My goal was to make player move just a little bit when it is attacking and when player is not attacking it can move normally. But right now if I press directional input and attack at the same time player can still moves normally.
This is my code:
extends CharacterBody2D
@export var speed: float = 100
@export var accel: float = 10
@export var dashing = false
@export var dashdistance: float = 300
@export var attacking = false
@export var attackdistance: float = 100
@export var dasheffect = preload("res://dasheffect.tscn")
@onready var anime = $AnimatedSprite2D
@onready var sword: Node2D = get_node("sword")
@onready var sword_anime: AnimationPlayer = get_node("sword/SwordAnimationPlayer")
@export var mouse_direction: Vector2 = (get_global_mouse_position() - global_position).normalized()
func _process(_delta: float) -> void:
var mouse_direction: Vector2 = (get_global_mouse_position() - global_position).normalized()
sword.rotation = mouse_direction.angle()
if mouse_direction.x > 0 and anime.flip_h:
anime.flip_h = false
elif mouse_direction.x < 0 and not anime.flip_h:
anime.flip_h = true
enum States {
MOVE,
ATTACK
}
var state = States.MOVE
func _physics_process(delta):
if attacking:
return
match state:
States.MOVE:
move(delta)
States.ATTACK:
attack()
func move(delta):
print("move")
var direction: Vector2 = Input.get_vector("left", "rihgt", "up", "down")
velocity.x = move_toward(velocity.x, speed * direction.x, accel)
velocity.y = move_toward(velocity.y, speed * direction.y, accel)
if velocity != Vector2.ZERO:
anime.play("run")
else:
anime.play("idle")
dash()
move_and_slide()
if Input.is_action_just_pressed("attack"):
state = States.ATTACK
func attack():
print("attack")
attacking = true
sword_anime.play("swing")
anime.play("attack")
if !Input.is_action_just_pressed("attack"):
state = States.MOVE
attacking = false
func dash():
var mouse_direction: Vector2 = (get_global_mouse_position() - global_position).normalized()
if Input.is_action_just_pressed("ui_accept"):
velocity = mouse_direction.normalized() * dashdistance
dashing = true
await get_tree().create_timer(0.2)
dashing = false
Upvotes: 0
Views: 310
Reputation: 1729
The problem is that you checking for an input in your attack function. So after switching into the attack state the very next frame the condition
!Input.is_action_just_pressed("attack")
will be true and you are moving back to the move state before the animation is finished.
There are multiple solutions how you could fix that. You could for example create a timer and determine, that your attack has a fixed duration and after the timer expired you could go back to the move state.
Or another way could be to use one of you attack animations as indicator, if your character is still attacking.
In my example I will be using your AnimationSprite with the attack animation: I will be using the animation_finished signal of the animated sprite. I connect it to the function on_animation_finished():
func attack():
print("attack")
attacking = true
sword_anime.play("swing")
anime.play("attack")
//nothing else to do here
//connected to the animation_finished signal of your node AnimatedSprite2D
func on_animation_finished():
if anime.animation == "attack":
state = States.MOVE
attacking = false
This way you will only return to the move state, if your attack animation is finished playing. If you do not want to use the signal, you could also move
if attacking:
return
from your physics process into you attack function and do the check there:
func attack():
if not attacking:
print("attack")
attacking = true
sword_anime.play("swing")
anime.play("attack")
//if the animation changed meanwhile, or it finished playing move back to state move
if anime.animation != "attack" or not anime.is_playing():
state = States.MOVE
attacking = false
Upvotes: 0