+2 votes

Hello,

I'm messing around with Godot 3.0 and am hitting an interesting issue with getting a simple character controller running with KinematicBody. It responds to the scene the way you would expect, but when moving at slightly higher speeds, it jitters quite a bit on every machine I've tried (Intel integrated 5000, and Nvidia gtx 1080ti).

It seems to be something in how its resolving movement. The visual artifact is it seems to be jumping between one frame ahead and behind in the simulation. (note: it only affects the capsule)

var move_speed = 6.0
var move_direction = Vector3()

func _ready():
    # Called every time the node is added to the scene.
    # Initialization here
    pass

func _process(delta):
    move_direction = Vector3(0, -0.3 ,0)

    if (Input.is_action_pressed("move_forward")):
        move_direction.z -= 1
    if (Input.is_action_pressed("move_backward")):
        move_direction.z += 1
    if (Input.is_action_pressed("move_left")):
        move_direction.x -= 1
    if (Input.is_action_pressed("move_right")):
        move_direction.x += 1

func _physics_process(delta):
    get_parent().move_and_slide(move_direction.normalized() * move_speed, Vector3(0,1,0))

I've also tried a version where all the code is in physicsprocess, as well as disabling the down-force, and turning off the interpolated camera. None of those things stop the jitter. It's present when moving in any direction, but most obvious when moving left and right.

Here is an example of a repro project: https://1drv.ms/u/s!AuWBWOrFX0CwmJYBG6Z6Y-_RlgX2sw

(arrow keys move)

I feel like this isn't a bug, and simply me doing something wrong... But I'm at a loss as to what it is T_T

in Engine by (48 points)

The first thing I'd check is that you haven't scaled the capsule. All sorts of collision problems can happen if the scale isn't (1, 1).

That's a good tip, I didn't know about that. All the scales applied to the capsule are (1,1,1) though.

I downloaded your test project and I only very occasionally get jittering. However, I ran the profiler and found that the jitter occurs when the engine starts dropping frames (which makes sense). I did some digging and it looks like there's already been quite a bit of discussion about this problem on Github. Here's a bunch of stuff I found.

https://github.com/godotengine/godot/issues/15270

https://github.com/godotengine/godot/issues/10388

https://github.com/godotengine/godot/issues/2043 (probably a bit outdated)

Looks like there are some things you could test on your systems to further diagnose the problem, particularly in that first link.

Thanks for the links!

What's interesting is I've moved the call to moveandslide into process, instead of physics_process, and it fixed everything.

Whats interesting is that I just realized that the docs never explicitly state that moveandslide needs to be called from physicsprocess.

I know traditionally you're supposed to modify physics objects on the fixed timestep... but this fixes the issue I'm seeing. Do you think it will bite me later if I do it this way?

My intuition tells me that using move_and_slide() outside of the physics process will cause issues, especially when you're dealing with conditional velocity in regards to collision states. My intuition has been wrong before though so it might be possible to pull off. You will probably still need to use physics process to do some things to ensure you're synced with the physics state.

1 Answer

+5 votes

I had a similar issue and solved it.

I too put move_and_slide() into the process(delta) function because it didn't jitter at first. But later there is a problem, framerates under and over 60fps will have slower or faster physics. It definitely should be in physics_process(delta) function.

I fixed the jitters by also moving my Camera script _process to _physics_process and I turned OFF smoothing. That might not work for everyone but so far it seems to work for me.

by (24 points)

Thanks for this! I was running into a very similar problem and moving my camera movements from _process to _physics_process worked perfectly.

I was tracking 1/1 and changing camera.position to equal target.position; I expected that it wouldn't matter but I guess it really did!

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.