Help with player movement

Godot Version

`4.3

Question

`Hello! Currently I am running into an issue in which if i am holding down an input, then i press another input in the opposite direction, my player will stop moving and the animation from the first input will still play. If I press “right” and then also press “left”, Id like to make it so that the second Input is ignored, but not ignored if pressing something like “right” and “up”. My player movement script is below, could someone please tell me a way to fix this problem?

func get_input():
var input_direction = Input.get_vector(“left”, “right”, “up”, “down”)
velocity = input_direction * basespeed

Code to control sprint speed

if Input.is_action_pressed("Sprint"):
	velocity *= 2.5

func _physics_process(delta):
get_input()

Code to control walking, running and idle animations for right facing

if Input.is_action_pressed("right") and Input.is_action_pressed("Sprint"):
	_body_animation.play("Male Right Side Run Base")
elif Input.is_action_pressed("right"):
	_body_animation.play("Male Right Side Walk")
elif Input.is_action_just_released("right"):
	_body_animation.play("Male Right Side Idle")

Code to control walking, running and idle animations for left facing

elif Input.is_action_pressed("left") and Input.is_action_pressed("Sprint"):
	_body_animation.play("Male Left Side Run Base")
elif Input.is_action_pressed("left"):
	_body_animation.play("Male Left Side Walk")
elif Input.is_action_just_released("left"):
	_body_animation.play("Male Left Side Idle")

Code to control walking, running and idle animations for up/back facing

elif Input.is_action_pressed("up") and Input.is_action_pressed("Sprint"):
	_body_animation.play("Male Back Run Base")
elif Input.is_action_pressed("up"):
	_body_animation.play("Male Back Walk")
elif Input.is_action_just_released("up"):
	_body_animation.play("Male Back Idle")

Code to control walking, running and idle animations for down/front facing

elif Input.is_action_pressed("down") and Input.is_action_pressed("Sprint"):
	_body_animation.play("Male Front Run Base")
elif Input.is_action_pressed("down"):
	_body_animation.play("Male Front Walk")
elif Input.is_action_just_released("down"):
	_body_animation.play("Male Front Idle")
	
move_and_slide()

See below my little demo how you could do that in your project:

Scene structure:

Code on the Player node:

extends CharacterBody2D

var speed: float = 200
var direction: Vector2
var is_up_pressed: bool
var is_down_pressed: bool
var is_left_pressed: bool
var is_right_pressed: bool

func _unhandled_input(event: InputEvent) -> void:
	if event.is_action_pressed("ui_up") and not is_up_pressed and not is_down_pressed:
		is_up_pressed = true
		direction += Vector2.UP
	if event.is_action_pressed("ui_down") and not is_down_pressed and not is_up_pressed:
		is_down_pressed = true
		direction += Vector2.DOWN
	if event.is_action_pressed("ui_left") and not is_left_pressed and not is_right_pressed:
		is_left_pressed = true
		direction += Vector2.LEFT
	if event.is_action_pressed("ui_right") and not is_right_pressed and not is_left_pressed:
		is_right_pressed = true
		direction += Vector2.RIGHT

	if event.is_action_released("ui_up") and is_up_pressed:
		is_up_pressed = false
		direction -= Vector2.UP
	if event.is_action_released("ui_down") and is_down_pressed:
		is_down_pressed = false
		direction -= Vector2.DOWN
	if event.is_action_released("ui_left") and is_left_pressed:
		is_left_pressed = false
		direction -= Vector2.LEFT
	if event.is_action_released("ui_right") and is_right_pressed:
		is_right_pressed = false
		direction -= Vector2.RIGHT


func _physics_process(delta: float) -> void:
	velocity = direction.normalized() * speed
	move_and_slide()
1 Like

Thank you for the help, i implemented the changes you suggested but now my character no longer sprints. I was multiplying speed by a number to achieve this, but my question to you is, can you explain what the unhandled_input function is doing? Also I am confused, why did you use

func _physics_process(delta: float) → void:
velocity = direction.normalized() * speed

instead of

func _physics_process(delta):

In order to use sprint, just add back your previous “sprinting” code to the _physics_process() after assigning velocity and before move_and_slide():

func _physics_process(delta: float) -> void:
	velocity = direction.normalized() * speed

	if Input.is_action_pressed("Sprint"):
		velocity *= 2.5
	
	move_and_slide()

To learn more about Input Handling, I recommend this article, this explains _unhandled_input() method as well.

And to answer your last question, this:

func _physics_process(delta: float) → void:

Is the same as this:

func _physics_process(delta):

Just statically typed. You can learn more about static typing here, which I would highly recommend:

Thank you so much for the help!

1 Like