2-directional movement turned to 4-directional mvmnt. And failed

Godot Version

4.3

Question

Hey guys!
My character just slides off the screen and I can’t figure out why.

Here’s my code from a tutorial for x-movement, which I tried to “hack” into a four-directional movement code. It is part of a state-machine where I call these functions in their respective states. Here’s (part of) the code:

func get_input_vector() -> Vector2:
	var input_vector = Vector2.ZERO
	input_vector = Input.get_vector("left", "right", "up", "down")
	return input_vector


func apply_movement(input_vector: Vector2, delta: float) -> void:
	velocity.x = lerp(velocity.x, input_vector.x * speed, acceleration)
	velocity.y = lerp(velocity.y, input_vector.y * speed, acceleration)


func apply_velocity(delta: float) -> void:
	move_and_slide()


func change_direction(direction) -> void:
	if sign(direction) == -1:
		sprite.flip_h = true
	elif sign(direction) == 1:
		sprite.flip_h = false

Somewhere my thinking went awry. If anyone sees something helpful I’d be glad if you have time for an answer!

I think you did not mentioned the main part of the codes, maybe physical process.

Try this (no sprite flipping code):

extends CharacterBody2D

var acceleration:float = 0.07
var speed:float = 400.0

func _physics_process(delta: float) -> void:
	apply_movement(get_input_vector(), delta)
	move_and_slide()

func get_input_vector() -> Vector2:
	return Input.get_vector("left", "right", "up", "down")
	
func apply_movement(in_vec: Vector2, dt: float) -> void:
	velocity = lerp(velocity, in_vec * speed, acceleration)
1 Like

@KingGD It used to work before without _physics_process()

Hey @lillycherry
This is pretty tough for me to work in since I am calling all of my functions in another script:

class_name MovingPlayer1State
extends State1


func enter() -> void:
	player1.sprite.play("move_1")


func exit() -> void:
	pass


func update(delta: float) -> void:
	var input_vector = player1.get_input_vector()
	
	player1.apply_movement(input_vector, delta)
	player1.change_direction(input_vector.x)
	player1.apply_velocity(delta)
	
	if input_vector.x == 0:
		transition.emit("IdlePlayer1State")
	if input_vector.y == 0:
		transition.emit("IdlePlayer1State")


func physics_update(delta: float) -> void:
	pass

Do I just change those calls to your functions? Thanks for your help!

No need to change your code to my example. You can calculate velocity in any place you like and pass result to you CharacterBody2D where you call move_and_slide(). Don’t forget that move_and_slide() should be in _physics_process (and probably your velocity calculations) since it handles collision with physical objects.

1 Like

Awesome! I git it working! Thanks. I have some higher speed on the y-axis than on the x-axis now. Would you have an Idea why that is?

I already checked the gravity setting and changes everything to zero. But without any changes.

You are probably modifying it somewhere in the code.
Try debugging with print() at each step where you changing values. First - your final velocity, and if Y-axis actually bigger than desired, check the code where you calculating it by printing out those values, and so on, walk backwards trough your code/functions. Also, i am pretty sure, that you don’t need to use “delta” with move_and_slide() function, so it may cause some buggy behavior. You can also change your CharacterBody2D “Motion_Mode” to “Floating”, to be sure, that gravity is not a factor.

1 Like

Fixed it! Thanks! There was a line in my IdleState that messed with x actually upon entering!

Thank you so much for your help!

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.