Godot Version
4.6.1 stable
Question
I’ve been working at a 3D camera controller for my game, and I wanted to add some headbob
similar to SCP: Containment Breach, and i’ve managed to make it somewhat work through a tutorial, but when moving the camera in a certain way, the camera inverts and affects the movement of the player. (The player starts walking backwards or diagonally instead of straight). I have tried certain ways to fix it aswell as looking into the forums, but I haven’t found a concrete answer, nor was I able to come up with a solution. Here’s the headbob code, the code itself is located in physics process:
if velocity.length() > 0 and is_on_floor():
t_bob += delta * velocity.length() * float(is_on_floor())
camera.transform.origin = _headbob(t_bob)
camera.rotation.z = _headbob2(t_bob)
else:
t_bob = 0
camera.transform.origin = lerp(camera.transform.origin, Vector3.ZERO, delta * 5)
camera.rotation.z = lerp(camera.rotation.z, 0.0, delta * 5)
And here’s the headbob functions:
func _headbob(time) -> Vector3:
var pos = Vector3.ZERO
pos.y = sin(time * BOB_FREQ) * BOB_AMP
return pos
func _headbob2(time):
var pos = Vector3.ZERO
pos.z = sin(time * BOB_FREQ / 2) * 0.025
return pos.z
Also a video demonstrating the issues:
If needed, I can send the whole code.
That’s called Gimbal Lock. You need to rotate on the x and y axes separately. This article in the Godot Docs talks about it: Using 3D transforms — Godot Engine (latest) documentation in English
The best way to handle this is to do something like this:
Where the SpringArm3D rotates on the y-axis and the Camera3D rotates on the x-axis.
In the above example, I am actually rotating the Pivot nodes and applying the rotation to them SpringArm3D and Camera3D nodes.
func _physics_process(delta: float) -> void:
horizontal_pivot.rotate_y(Controller.look.x)
vertical_pivot.rotate_x(Controller.look.y)
vertical_pivot.rotation.x = clampf(vertical_pivot.rotation.x,
deg_to_rad(upwards_rotation_limit),
deg_to_rad(downwards_rotation_limit)
)
spring_arm_3d.rotation.y = horizontal_pivot.rotation.y
camera_3d.rotation.x = vertical_pivot.rotation.x
For full code, you can check out my Camera3D Plugin and Character3D Plugin.
Thank you for responding, had no idea those limitations existed until now. However, is this something that I have to use your plugin for? I wouldn’t mind if that’s the case, but I’m just wondering if there’s another solution to this. (Edit: I also noticed that this seems to be the code for the camera movement code, not the actual headbob. So I assume I only change that and not the code that I provided? I apologize if I’m asking too many questions.)
You can fix it yourself. I was just showing you an example. The headbob should not be affected. You can also find videos online for fixing gimbal lock.
Alright, got it. Thank you.