Godot Version
4.2.2
Question
Hi, i need help, my character for some reason enters on the stunned state two times, i added some prints in there to debug the change of the states, and i tried add some boolean variables to stop the change but i keeps changing the state again, the code of the state machine is this one:
class_name CharacterStateMachine
extends Node
@export var rising_gravity : int = 15
@export var fast_falling_gravity : int = 20
@export var _character : CharacterBody2D
@export var current_state : State
@export var attacked_state : State
var _states : Array[State]
func _ready():
for child in get_children():
if (child is State):
_states.append(child)
child._character = _character
else:
push_warning("Child " + child.name + “is not in State for this Character”)
func _physics_process(delta):
if(current_state.next_state != null):
switch_states(current_state.next_state)
current_state.state_process(delta)
func switch_states(next_state : State):
if(current_state != null):
current_state.on_enter_state()
current_state.next_state = null
current_state = next_state
current_state.on_enter_state()
func check_if_can_move():
return current_state.can_move
func check_if_can_jump():
return current_state.can_jump
func check_if_is_stunned():
return current_state.is_stunned
func apply_gravity():
if(current_state.apply_gravity):
if(!_character.is_on_floor()):
_character.velocity.y += rising_gravity
if(_character.velocity.y > 0):
_character.velocity.y += fast_falling_gravity
_character.move_and_slide()
func _input(_event : InputEvent):
current_state.state_input(_event)
and this one is the idle state, where it returns:
class_name IdleState
extends State
@export var brax_actions_animation_player : AnimationPlayer
@export var brax_state_machine_functions: CharacterStateMachine
@export var air_state : State
@export var walking_state : State
@export var attack_state : State
@export var idle_state : State
@export var brax_jump_sound_effect : AudioStreamPlayer2D
func state_process(delta):
brax_actions_animation_player.speed_scale = 1.0;
_apply_state_gravity()
_walk()
_when_character_is_on_floor()
func state_input(_event : InputEvent):
if (
_event.is_action_pressed("JUMP") and
brax_state_machine_functions.check_if_can_jump()
):
_jump()
elif (
_event.is_action_pressed("NORMAL_ATTACK") and
_character.velocity.y == 0
):
_floor_attack()
if (
Input.is_action_pressed("UP") and
_event.is_action_pressed("SECONDARY_ATTACK") and
_character.is_on_floor()
):
_uppercut_attack()
func _apply_state_gravity():
brax_state_machine_functions.apply_gravity()
func _when_character_is_on_floor():
if _character.is_on_floor():
_character.velocity = Vector2.ZERO
func _walk():
if brax_state_machine_functions.check_if_can_move():
if Input.is_action_pressed("RIGHT"):
next_state = walking_state
elif Input.is_action_pressed("LEFT"):
next_state = walking_state
func _uppercut_attack():
brax_actions_animation_player.play("up_punch_buildup")
brax_actions_animation_player.speed_scale = 3.0
next_state = attack_state
func _jump():
brax_jump_sound_effect.play()
_character.velocity.y = base_jump_height
next_state = air_state
func _floor_attack():
next_state = attack_state
brax_actions_animation_player.speed_scale = 2.0
brax_actions_animation_player.play("punch_normal")
and this one is the, walk state, where it enters to the stunned state:
class_name WalkingState
extends State
@export var getting_hit_area : Area2D
#Enemigos que seran detectados por el jugador
@onready var lurker_enemy = get_tree().get_first_node_in_group("Enemies")
@export var brax_state_machine_functions : CharacterStateMachine
@export var brax_sprite : Sprite2D
#Estados Cambio
@export var idle_state : State
@export var air_state : State
@export var dash_state : State
@export var attack_state : State
@export var stunned_state : State
@export var brax_jump_sound_effect : AudioStreamPlayer2D
@export var brax_actions_animation_player : AnimationPlayer
func state_process(delta):
_apply_state_gravity()
_walk()
_stop_walk()
_after_falling_of_a_platform()
_attack_while_walking()
func state_input(_event : InputEvent):
if (
_event.is_action_pressed("JUMP") and
_character.is_on_floor() and
brax_state_machine_functions.check_if_can_jump()
):
_jump()
if (
Input.is_action_pressed("RIGHT") and
_event.is_action_pressed("DASH")
):
next_state = dash_state
if (
Input.is_action_pressed("LEFT") and
_event.is_action_pressed("DASH")
):
next_state = dash_state
func _walk():
if brax_state_machine_functions.check_if_can_move():
if Input.is_action_pressed("RIGHT"):
brax_sprite.flip_h = false
_character.velocity.x = walk_speed
elif Input.is_action_pressed("LEFT"):
brax_sprite.flip_h = true
_character.velocity.x = -walk_speed
func _stop_walk():
if (
Input.is_action_just_released("RIGHT") and
not _character.velocity.x < 0
):
_character.velocity = Vector2.ZERO
elif (
Input.is_action_just_released("LEFT") and
not _character.velocity.y > 0
):
_character.velocity = Vector2.ZERO
elif _character.velocity == Vector2.ZERO:
next_state = idle_state
func _apply_state_gravity():
brax_state_machine_functions.apply_gravity()
func _after_falling_of_a_platform():
if _character.velocity.y > 0 :
_character.velocity = Vector2.ZERO
next_state = air_state
func _attack_while_walking():
if Input.is_action_just_pressed("NORMAL_ATTACK"): #Detener el movimiento mientras brax ataca al moverse
_character.velocity.x = 0
next_state = attack_state
func _jump():
brax_jump_sound_effect.play()
_character.velocity.y = base_jump_height
next_state = air_state
func _on_getting_hit_body_entered(body):
print("KNOCBACK POR CAMINAR")
body = lurker_enemy
next_state = stunned_state
and this one is the stunned state:
class_name StunnedState
extends State
@export var brax_state_machine_functions : CharacterStateMachine
@export var brax_actions_animation_player : AnimationPlayer
@onready var lurker_enemy = get_tree().get_first_node_in_group("Enemies")
@export var idle_state : State
func on_enter_state():
print("STUNNEADO")
brax_actions_animation_player.play("damage_taken")
var knockback_direction = (_character.global_position - lurker_enemy.global_position).normalized()
_character.velocity = 170 * knockback_direction
_character.velocity.y = -300
func state_process(delta):
_apply_state_gravity()
func _apply_state_gravity():
brax_state_machine_functions.apply_gravity()
func _on_brax_actions_animations_animation_finished(anim_name):
if anim_name == "damage_taken" && _character.is_on_floor():
_character.velocity = Vector2.ZERO
next_state = idle_state
in the stunned state, there is a knockback effect, that is applied even, when it changes to the idle state, i would greatly appreciate the help, this bug is making me crazy