4-directional character movement with idle and run function

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

extends KinematicBody2D

var velocity: Vector2 = Vector2()

const friction = 100
const acc = 70
const walk_speed = 150
const run_speed = 600

var is_running = null

func _process(delta):
move()
move_and_slide(velocity)

func move():
velocity = Vector2()

if Input.is_action_pressed("ui_left"):
	velocity.x = -walk_speed
	$AnimatedSprite.play("Left_Walk")
elif Input.is_action_pressed("ui_left") and Input.is_action_pressed("run"):
	velocity.x = -run_speed
	$AnimatedSprite.play ("Left_Run")
elif Input.is_action_just_released("ui_left"):
	$AnimatedSprite.play("Left_Idle")
elif Input.is_action_pressed("ui_right"):
	velocity.x = walk_speed
	$AnimatedSprite.play("Right_Walk")
elif Input.is_action_just_released("ui_right"):
	$AnimatedSprite.play("Right_Idle")
elif Input.is_action_pressed("ui_up"):
	velocity.y = -walk_speed
	$AnimatedSprite.play("Back_Walk")
elif Input.is_action_just_released("ui_up"):
	$AnimatedSprite.play("Back_Idle")
elif Input.is_action_pressed("ui_down"):
	velocity.y = walk_speed
	$AnimatedSprite.play("Front_Walk")
elif Input.is_action_just_released("ui_down"):
	$AnimatedSprite.play("Front_Idle")

The line where I have entered two inputs with “and” does not work, no difference in animation or speed, what am I doing wrong? Also all comments are welcomed about improving the code.
Essentially what I want is:

  1. a character that walks in 4 directions (done, sort of)
  2. stops and stays idle in the direction they walked
  3. runs in all those directions while shift is held

Thanks for the help!

:bust_in_silhouette: Reply From: AndyCampbell

When you use if and elif, the first option which is true will be executed, and when that option is executed, the rest of the options will not be evaluated. The logic will not try to find multiple options and select the “best fit”

So, in your case, when Input.is_action_pressed(“ui_left”) is true, the first if statement executes and the other options never get evaluated. So, I think the logic can never reach the “Left Run” option if “Left Walk” is true

You could try flipping the order to put the lines with “and” first…

Alternatively, you can see that using that if/elif construction can get very complicated because you might require many combinations. In this scenario it might be a great idea to use a state machine which tracks the state of your character and all the options that can be reached from that state

You can see a super introduction to the state machine model here

Thanks so much, I was also doing some investigating while the question remained up and have since changed most of my code to better understand it. Thanks again!

Cryothenir | 2023-02-24 14:50