Godot Version
4.2
Question
So… I’ve created a FSM within the player script and am running into a small issue with the dash and movement.
Dash: In-short I simply want to have the dash timed. So after 0.5 seconds the player will stop moving no matter if they hold or press the dash key.
Movement: I’m trying to create a celeste dash, basically where the player is unable to change direction during the dash.
extends CharacterBody2D
class_name PC
var walk_speed = 250
var dash_speed = 600
var accel = 100
var direction: Vector2
var dash_vector = Vector2.LEFT
enum States { Idle, Move, Dash, Death }
var state = States.Idle
func change_state(newstate):
state = newstate
func _physics_process(delta):
match state:
States.Idle:
IdleData()
States.Move:
MoveData(delta)
States.Dash:
DashData()
States.Death:
DeathData()
func IdleData():
print("Idle")
pass
func MoveData(delta):
print("move")
direction = Input.get_vector("Key_Left", "Key_Right", "Key_Up", "Key_Down")
velocity = lerp(velocity, walk_speed * direction, accel * delta)
velocity.normalized()
move_and_slide()
func DashData():
print(velocity)
if direction != Vector2.ZERO:
dash_vector = direction.normalized()
velocity = dash_speed * dash_vector
move_and_slide()
func DeathData():
pass
func _input(delta): #add death event for once PC dies
if Input.is_action_just_pressed("Dash"):
change_state(States.Dash)
elif Input.get_vector("Key_Left", "Key_Right", "Key_Up", "Key_Down"):
change_state(States.Move)
else:
change_state(States.Idle)
You can use a one-shot timer like this to change state from dash to idel after 0.5s.
get_tree().create_timer(0.5).timeout.connect(change_state.bind(States.Idle))
To stop the player from moving when dashing, you can use a guard in form of a bool i.e
var can_move: bool = true
When state is changed to dash, set can_move to false. Before changing state to move in _input, check first if can_move is true.
To reset can_move to true after dash is complete, the updated one shot timer will look like this:
func _input(delta):
...
if Input.is_action_just_pressed("Dash"):
can_move = false
change_state(States.Dash)
##This calls the _end_dash function after 0.5seconds
get_tree().create_timer(0.5).timeout.connect(_end_dash)
...
func _end_dash() -> void:
change_state(States.Idle)
can_move = true
The movement works, but the dash doesn’t end if I’m holding it. Also if I’m not moving prior to pressing the dash key, the dash wont work at all.
func MoveData(delta):
print("move")
if !is_dashing:
direction = Input.get_vector("Key_Left", "Key_Right", "Key_Up", "Key_Down")
velocity = lerp(velocity, walk_speed * direction, accel * delta)
velocity.normalized()
move_and_slide()
func DashData():
print(velocity)
if direction != Vector2.ZERO:
is_dashing = true
$dash_timer.start()
dash_vector = direction.normalized()
velocity = dash_speed * dash_vector
move_and_slide()
func DeathData():
pass
func _input(delta): #add death event for once PC dies
if Input.is_action_just_pressed("Dash") && can_dash && !is_dashing:
change_state(States.Dash)
elif Input.get_vector("Key_Left", "Key_Right", "Key_Up", "Key_Down"):
change_state(States.Move)
else:
change_state(States.Idle)
func _on_dash_timer_timeout():
is_dashing = false
strifethedev_0:
elif Input.get_vector("Key_Left", "Key_Right", "Key_Up", "Key_Down"):
change_state(States.Move)
else:
change_state(States.Idle)
Not sure what is wrong, but are you sure your code can reach the point it changes to Idle? You should add a print statement there to be sure it changes to Idle.
The easiest way will be to just change to idle when dash timer is finished.
1 Like
system
Closed
March 30, 2024, 10:09am
5
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.