ver 4.3
Hi , I’m trying to add an state machine to my player but i cant figure out this one problem, i want the player to not do anything when attacking , I added an timer so once it runs out the player can switch states and move again however the timer ain’t is not switching states , please help.
players code:
,
extends CharacterBody2D
var speed = 130
const dash_speed = 400
@onready var dash_timer: Timer = $dash_timer
@onready var attack_timer: Timer = $attack_timer
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
@onready var animation_player: AnimationPlayer = $AnimatedSprite2D/AnimationPlayer
@onready var animation_tree: AnimationTree = $AnimatedSprite2D/AnimationTree
enum states{Movement, Attack, Dash}
var current_state : int = 0
var state = states.Movement
var attacking = false
var dashing = false
func change_state(new_state : int) → void:
state = new_state
#basic player movements
func movement():
var direction = Input.get_vector(“move_left”, “move_right”, “move_up”, “move_down”)
velocity = direction * speed
if Input.is_action_just_pressed("Attack"):
change_state(states.Attack)
func attack():
attacking = true
attack_timer.start()
func _physics_process(_delta: float) → void:
match state:
states.Movement:
movement()
move_and_slide()
states.Attack:
attack()
,
So I commented out bits of your code that were not relevant to the sample and created a CharacterBody2D and added your script.
I had to change your movement names to ui variables for ease. I also added a timer and a collision shape just to keep the editor happy. Oh, and an animated sprite of course too. So this code now seems to be doing what you wanted.
The main problem was that you were not checking for the timers timeout signal. I did this in code below but it is much easier to use the built in timer signals in the inspector for that. Either way it still works.
You were also continually calling the Attack state so the timer was restarting and would never timeout. So given the code you presented here are some amendments that mean you move the sprite, you press attack, it waits for the timer to timeout, then you can move again. Hope it helps in some way.
extends CharacterBody2D
var speed: float = 130
const dash_speed: float = 400
#@onready var dash_timer: Timer = $dash_timer
@onready var attack_timer: Timer = $attack_timer
@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D
#@onready var animation_player: AnimationPlayer = $AnimatedSprite2D/AnimationPlayer
#@onready var animation_tree: AnimationTree = $AnimatedSprite2D/AnimationTree
enum states{Movement, Attack, Dash}
var current_state : int = 0
var state: int = states.Movement
var attacking: bool = false
var dashing: bool = false
func _ready() -> void:
attack_timer.timeout.connect(_on_attack_timer_timeout)
func _physics_process(_delta: float) -> void:
match state:
states.Movement:
movement()
move_and_slide()
states.Attack:
attack()
func change_state(new_state: int) -> void:
state = new_state as states
func movement() -> void:
var direction: Vector2 = Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
velocity = direction * speed
if Input.is_action_just_pressed("ui_accept"):
change_state(states.Attack)
func attack() -> void:
if attacking:
return
attacking = true
attack_timer.start()
func _on_attack_timer_timeout() -> void:
attacking = false
change_state(states.Movement)
1 Like
thanks so much , the player can move when the timer runs out , i was so clueless on how to fix it.
1 Like