Need help as a beginner

I am very new to godot and gdscript and Ive hit a roadblock relating to my first state machine on my first game. Im trying to make a basic movement system made up of 4 movements: left boost, right boost(these would automatically move the player a certain distance while allowing for vertical movement and would not be a teleporter), dodge(temporarily disables collision while still allowing for movement), and normal movement(up, down, left, and right). Im trying to make my game similar to the flight sections of cuphead so theres no gravity.

My issue is that the animations do not respond to key inputs as their supposed to and only the normal movement seems to be working. This probably has a very simple solution but I cant figure it out. I dont have any programming experience outside of high school java courses.

extends CharacterBody2D

enum States {DODGE, LEFT_BOOST, RIGHT_BOOST, MOVE}
var speed = 200
@onready var timer: Timer = $Timer
@onready var collision: CollisionShape2D = $head_target
@onready var animation: AnimatedSprite2D = $animations
var state: States = States.MOVE

func set_state_animation(new_state: States) -> void:
	state = new_state
	match state:
		States.DODGE:
			animation.play("dodge")
		States.LEFT_BOOST:
			animation.play("left boost")
		States.RIGHT_BOOST:
			animation.play("right boost")
		States.MOVE:
			animation.play("idle")

func _unhandled_input(event: InputEvent) -> void:
	if Input.is_action_just_pressed("dodge"):
		state == States.DODGE
	elif Input.is_action_just_pressed("left boost"):
		state == States.LEFT_BOOST
	elif Input.is_action_just_pressed("right boost"):
		state == States.RIGHT_BOOST
	elif Input.is_action_just_pressed("right") or ("left") or ("up") or ("down"):
		state = States.MOVE

func _physics_process(delta: float) -> void:
	if state == States.DODGE:
		timer.start()
		collision.disabled = true
		if timer.time_left <= 0:
			state == States.MOVE
			collision.disabled = false
	elif state == States.LEFT_BOOST:
		velocity.x = 0
		position.x -= delta * speed * 2
		velocity.y = speed
		move_and_slide()
		if position.x <= -2 * speed:
			state == States.MOVE
	elif state == States.RIGHT_BOOST:
		velocity.x = 0
		position.x += delta * speed * 2
		velocity.y = speed
		move_and_slide()
		if position.x >= 2 * speed:
			state == States.MOVE
	elif state == States.MOVE:
		var X_axis := Input.get_axis("left", "right")
		if X_axis:
			velocity.x = X_axis * speed
		else:
			velocity.x = move_toward(velocity.x, 0, speed)

		move_and_slide()
		
		var Y_axis := Input.get_axis("up", "down")
		if Y_axis:
			velocity.y = Y_axis * speed
		else:
			velocity.y = move_toward(velocity.y, 0, speed)

		move_and_slide()

Your input handling code is a bit wrong. You should be checking on the event parameter, not the singleton Input, if you’re using the unhandled input function.
And when checking for multiple scenarios like in your last elif, you can’t just omit the event.is_action_pressed, you still need to write that. Because you didn’t write that, this part of the code always resolved to true, because a non empty String resolves to true, so your whole line was basically “elif false or true or true or true”, which resolves to true.
Here’s a fixed version that should work better.

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("dodge"):
		state = States.DODGE
	elif event.is_action_pressed("left boost"):
		state = States.LEFT_BOOST
	elif event.is_action_pressed("right boost"):
		state = States.RIGHT_BOOST
	elif event.is_action_pressed("right") or event.is_action_pressed("left") or event.is_action_pressed("up") or event.is_action_pressed("down"):
		state = States.MOVE
1 Like

Thanks for the help though my animations still wont trigger and only basic movement is working(boosts arent speeding up the character and dodges arent working). My intention when making the code was for the set_state_animation and _physics_process functions to activate when _unhandled_input sensed the key input. Also the animation for basic movement is the default animation if that means anything.

I just noticed you were using double equal sign
state == States.DODGE instead of single state = States.DODGE. The double equal sign only compares values, while single equal sign assigns value to a variable. You should be doing the latter.
I corrected the code in my previous post.

Also make sure that your states are long enough for you to notice anything, because just looking at the code some of the states might be trigger for just 1 frame.
Try to print to the consol each state change just to be sure that your states actually change.

I did what you said and now the code is doing roughly what it is supposed to be doing. Thanks a lot.

1 Like