issue with fsm using match statements and changing states outside of it - Found a Solution

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

I’m currently reworking the crouching system for my game so that it uses a fsm that uses match statements to change states.

here is an example of the code for that.

enum Crouch_States{
	UPRIGHT,
	CROUCHING,
	CROUCHED,
	STANDING
}

var crouch_fsm_states = Crouch_States.UPRIGHT


func crouch_system():
	match crouch_fsm_states:
		Crouch_States.UPRIGHT:
			crouch_anim.play("Upright")
			if Input.is_action_just_pressed("crouch") and crouch == false or $head/head_RayCast.is_colliding() and crouch == true:
				print("check")
				crouch = true
				crouch_fsm_states = Crouch_States.CROUCHING
		Crouch_States.CROUCHING:
			crouch_anim.play("crouching")
			yield($crouch_anim,"animation_finished")
			crouch_fsm_states = Crouch_States.CROUCHED
		Crouch_States.CROUCHED:
			if Input.is_action_just_pressed("crouch") and crouch and $head/head_RayCast.is_colliding() == false:
				print("check")
				crouch = false
				crouch_fsm_states = Crouch_States.STANDING
			crouch_anim.play("crouched")
		Crouch_States.STANDING:
			crouch_anim.play("standing")
			yield($crouch_anim,"animation_finished")
			crouch_fsm_states = Crouch_States.UPRIGHT

but when I try to change states via reloading, it ceases to function and I am unable to change states again.

here is the code for saving and loading, its does not save to disk yet (also PlayerSaveData is Resource is a custom class that extends Resource)

 onready var PlayerData = PlayerSaveData.new()
 func save_game():
    	PlayerData.health = health
    	PlayerData.position = self.translation
    	PlayerData.rot = self.rotation
    	PlayerData.c_rot = $pivot.rotation.x
    	PlayerData.velocity = velocity
    	PlayerData.crouch = crouch_fsm_states
    	print("data saved")
    
    func load_game():
    	health = PlayerData.health
    	self.translation = PlayerData.position
    	self.rotation = PlayerData.rot
    	$pivot.rotation.x = PlayerData.c_rot
    	velocity = PlayerData.velocity
    	crouch_fsm_states = PlayerData.crouch
    	print("data loaded")

and here is a debug function that i used try and figure if it had anything to do with the saving and loading code.

func cheats():
	if Input.is_action_just_pressed("ui_accept"):
		crouch_fsm_states = Crouch_States.CROUCHING
		print(crouch_fsm_states)

This had the same result as changing states using the save and load functions

I’ve tried changing from match statements to if statements but that didn’t seem to do anything.

any ideas on what the problem is and how to fix it would be very much appreciated.

EDIT

I found a solution!

here is my code for the fixed fsm

func crouch_system():
	match crouch_fsm_states:
		Crouch_States.UPRIGHT:
			if crouch:
				crouch_fsm_states = Crouch_States.CROUCHED
			crouch_anim.play("Upright")
			if Input.is_action_just_pressed("crouch") and crouch == false or $head/head_RayCast.is_colliding() and crouch == true:
				print("check")
				crouch_fsm_states = Crouch_States.CROUCHING
		Crouch_States.CROUCHING:
			crouch_anim.play("crouching")
			yield($crouch_anim,"animation_finished")
			crouch_fsm_states = Crouch_States.CROUCHED
			crouch = true
		Crouch_States.CROUCHED:
			if Input.is_action_just_pressed("crouch") and crouch and $head/head_RayCast.is_colliding() == false:
				print("check")
				crouch_fsm_states = Crouch_States.STANDING
			crouch_anim.play("crouched")
			if not crouch:
				crouch_fsm_states = Crouch_States.UPRIGHT
		Crouch_States.STANDING:
			crouch_anim.play("standing")
			yield($crouch_anim,"animation_finished")
			crouch_fsm_states = Crouch_States.UPRIGHT
			crouch = false

basically the UPRIGHT and CROUCHED states now have a check that will kick it to either one which I now store when saving.

I’m not sure why this works and why it was getting stuck before but at least its fixed now!