How can I script smooth movement for KinematicBody2D?

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

I hope this is the correct category.

I’m making the simplest game possible: you move an icon around with buttons, but the movement seems jittery, not smooth at all. So I made the simplest possible version:

func _process(delta):
	move_and_collide(Vector2(10,0))

I also tried using move_and_slide and _physics_process, but none of the 4 versions worked, although the amount of jitter was different.

I made a video of it:

https://drive.google.com/file/d/1S7ncKm084BstVli8wpHZSTd7ZfLKKNAL/view?usp=sharing

So, how do I make the movement smooth? What am I missing here?

Can you try in 3.1 alpha? there are some issues with camera updating and other things that makes some jittering in particular situations and most of these are solved on 3.1.

Other sources of jittering are the vsync and driver settings that can mess up the update, sometimes forcing 60fps in project settings seems to help.

And do not use physics-related methods (like move) outside physics process because that will mess up collisions.

eons | 2018-12-29 17:32

:bust_in_silhouette: Reply From: uzimonkey

So first off, you’re calling move_and_collide with a constant value. I know the docs can be a little bit fuzzy, but jump straight to the source and you’ll see that it’s not multiplying by delta for you. You’re trying to move a constant amount per frame and frame times can vary. Instead you should want to move a constant amount per second, so you definitely want to multiply whatever you pass to move_and_collide by delta if you’re calling this from _process. Ideally you’ll want to multiply by delta if you call it from _physics_process as well, since if you ever change your physics tick rate things will start moving at different speeds. In general you want to represent speeds in units per second and multiply by delta always.

This is a bit confusing, but the same is not true about move_and_slide since it multiplies by delta for you and even more confusingly you don’t even have to pass delta to it so you might not know that’s happening. The move_and_slide function uses the physics delta in 3.0 no matter what function you call it from and in 3.1 it checks to see if you’re in _process or _physics_process and uses the correct delta. So move_and_slide should work correctly in _process after 3.1.

You should try this again in a build. I’ve been having trouble with the game stuttering a bit when run from the editor but being completely smooth in a build. I quickly rebuilt what you have and it does run choppy in editor, but smooth in a build using move_and_collide in _process. For reference, this is the script that runs smoothly.

extends KinematicBody2D
const SPEED = 100.0

func _physics_process(delta):
	var input = Vector2()
	input.x += float(Input.is_action_pressed('ui_right'))
	input.x -= float(Input.is_action_pressed('ui_left'))
	input.y -= float(Input.is_action_pressed('ui_up'))
	input.y += float(Input.is_action_pressed('ui_down'))
	
	if input.length() != 0:
		input = input.normalized()
	
	move_and_collide(input * SPEED * delta)

If you game has no dynamic bodies, everything should be fine calling these types of functions that move kinematic bodies around from the _process function. This will produce the smoothest output and you won’t even have to worry about the physics tick rate. Just know that you really can’t change the physics threading model in the project settings if you’re calling these functions from _process.

thank you for this this has messed me up for a long time i wish it was a lot clearer in the docs this has fixed my broken game. (after leaning this and reviewing my code i realized i was multing my movement by delta 3 times. my code was messed up i had the movement *delta then the move and slide * delta then the move and slide) headache gone!

David Thornton | 2019-08-24 13:22