How to have analog controls with joystick

Godot Version



Hi! I created a CharacterBody2D that I called Player and I attached an img to it, and I want to move the character around using the left stick of my joycon controller (the only stick really).
In order to do so, I created actions in the Input Map settings, and then created a script in my Player node, with the following code:

extends CharacterBody2D

var speed = 1500

# Called when ready
func _ready():

# Get the player's inputs
func get_input():
	var input_direction = Input.get_vector("move_left", "move_right", "move_up", "move_down")
	velocity = input_direction * speed

# Update physics process
func _physics_process(delta):

When I move my stick, my player move, but it’s not working as intended because it moves the same way it would with buttons or gamepad cross instead of analog stick (what I mean is that it ‘snap’ to the X and Y axis, not sure how to explain this). How am I supposed to move the img in an ‘analog way’ using my stick, the same way it would if, for example, the img was following my mouse cursor?

Thanks for your help!

I’m not sure if I understand correctly. I’ve tried your script and it works as expected as in the CharacterBody2D moves according to the Vector2 that gets applied.

If you are referring to creating more “natural” movement as in easing and curving the direction, you might need to implement some kind of inertia.

You could then lerp between the desired direction/velocity and the CharacterBody2Ds actual direction/velocity.

This is how I’m doing it in C#:

movementInput = Input.GetVector("move_left", "move_right", "move_forward", "move_backward");
movementDirection = new Vector3(movementInput.X, 0, movementInput.Y).Rotated(Vector3.Up, playerCameraPivotHorizontal.Rotation.Y).Normalized();

if (movementDirection != Vector3.Zero)
	velocity.X = (-movementDirection.X * moveSpeed) * movementInput.Length();
	velocity.Z = (-movementDirection.Z * moveSpeed) * movementInput.Length();

	animationSpeedX = Mathf.MoveToward(animationSpeedX, movementInput.X, lerpSpeed);
	animationSpeedY = Mathf.MoveToward(animationSpeedY, movementInput.Y, lerpSpeed);
	velocity.X = Mathf.MoveToward(Velocity.X, 0, moveSpeed);
	velocity.Z = Mathf.MoveToward(Velocity.Z, 0, moveSpeed);

	animationSpeedX = Mathf.MoveToward(animationSpeedX, 0, lerpSpeed);
	animationSpeedY = Mathf.MoveToward(animationSpeedY, 0, lerpSpeed);

So, basically I’ve created a new movement vector based on the camera position, and I’m multiplying that by the length of the input vector, so it reacts to how much or how little I’m pushing the left stick.

Hope that helps!

EDIT: Mine is in 3D, but I would imagine the idea should work just fine in 2D.

Hi, thanks for your answer! I think you guys are right, I tested my code again and it feels ok. I guess I just had a weird feeling when I was playing it a few days ago? I mean, having a controller is obviously not the best gamefeel to move a cursor around (mouse feels much better), but I’m creating a local multiplayer game so it has to be played with controller.

CreatureWOSpecies, I may try your method at some point, thanks!
Thanks again for your help.