I have a 144hz monitor and I’ve been having jittering issues when moving around in my first person game. I heard online that moving the camera separate from the player physics was the solution so I tried that by coding my camera to follow my player’s global position camera.position = player.global_position. But the jittering issue persisted. I then decided to use lerp to move the camera camera.position = camera.position.lerp(head.global_position, delta*30) and that kind of seems to fix the jittering issue, but I don’t know if that’s the correct solution, it definitely feels smoother but I feel like it could be even more smoother lol. Thanks for reading.
I think what you’re doing is that you have your camera movement code in _physics_process() use _process() instead _physics_process() runs 60 times per second by default
Is your position smoothing enabled in your camera (I think it is on by default but not sure). It makes a big difference.
I used to lerp my camera directly but now I treat my camera like a player or enemy node. It has a speed, an acceleration, a state manager for different behaviours and motions etc. It took ages to get it right. I also use a PlayerManager autoload singleton to share the players position, not only with the camera but with my enemy nodes as well.
PS I still use lerps for any camera motion, but I lerp everything
You can use lerp properly with Engine.get_physics_interpolation_fraction(), this will only leave your camera one frame behind
Engine.get_physics_interpolation_fraction() returns 0.0 to 1.0 the progress between physics frames. i.e. at 120hz refresh rate, and 60 physics tick this will usually be 0.0 (on physics tick) or 0.5 (refreshed between a physics tick)
lerp takes two values and returns a mid-point based on the final “weight” parameter, where 0.0 is the first argument, 1.0 is the second argument, and anything in-between is calculated.
@export var player: Node3D
var player_last_position: Vector3
func _process(_delta: float) -> void:
var new_position = player_last_position.lerp(player.global_position, Engine.get_physics_interpolation_fraction())
camera.position = new_position
# trying to capture the player's position after a physics update,
# might be best to have the player send this information upwards
# with a signal after move_and_slide() for instance
func _physics_process(_delta: float) -> void:
player_last_position = player.global_position
Your code should’ve ended up with a pretty smooth camera, make sure the jitter doesn’t come from frame lag, use the profilier or in the 3D view click “Perspective > View frame time”
This would not work as Godot does not have 3D physics interpolation bulit-in, and the player being a physics object only updates position at the physics tick rate.
I can’t notice the difference between using Engine.get_physics_interpolation_fraction() or using what I currently have delta * 30, don’t know if my eyes are just deceiving me, but any FP game just feels so smooth looking around at 144 fps compared to what I have. I might try doing something similar in unity just to compare.