# Camera clamp not working when the camera is tilted on a Z Axis

4.2.2.Stable

### Question

Hey!, so i made this headbob with the help of a fellow forum user but it seems like clamp stops working when it’s rotated

here’s a video showing what i mean:

``````#Bob variables
const BOB_FREQ = 2
const BOB_AMP = 0.08
const BOB_AMP_Y = 0.03
const BOB_FREQ_Y = 1
var t_bob = 0.0

func _physics_process(delta):
###
t_bob += delta * velocity.length() * float(is_on_floor())

var pos = Vector3.ZERO
pos.y = sin(time * BOB_FREQ) * BOB_AMP
pos.x = sin(time * BOB_FREQ/2) * BOB_AMP
camera.rotation.z = sin(t_bob * BOB_FREQ_Y) * BOB_AMP_Y
return pos
``````

How do i fix this? am i stupid

If you use clamp on a vector be advised that it will clamp all values and not just one. You need to clamp each axis separately.

So if you use the vector 3 clamp

``````Vec3 = (-1,.5,.5)

Vec3 = Vec3.clamp(vector.zero, vector.one)

Print(vec3)
# (0,0,0) , because it will clamp all axis.

``````

You should clamp like this on a vector

``````Vec3 = vector3(
clamp(vec3.x, 0, 1 ),
clamp(vec3.y, ... Etc.
``````

My guess is that there is more likely a chance that the camera is hitting the clamped boundary when your bob is enabled.

1 Like

how exactly do i implement that? i am fairly new so i don’t really know

Can you share your camera rotation code? Or the code that uses clamp? If you use clamp?

here:

``````@onready var pivot = \$Pivot

#Mouse
Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)

func _unhandled_input(event):
if event is InputEventMouseMotion:
pivot.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_x(-event.relative.y * SENSITIVITY)
``````

So you aren’t using clamp in the way I described, but there probably is some subtle math in here… Give me a sec

1 Like

[ edit: this is not correct statement about rotation values, the range is -pi to pi ]

I’m wondering about these function calls. Typically rotation is in radians from 0 to 2π(for 0° to 360°). There is no negative radian values. So I’m wondering if this is actually working as expected.

The other thing is that you change the rotation first and then clamp. It could be possible that the relative movement of the mouse is high enough that you could shoot past the clamp zone.

In the past I have used basis vectors y and z to determine the camera limits.

how is it supposed to look like? i’m curious

One sec I need to get to my computer.

I guess another other thing is that since you are rotating on the z axis for bobing your camera may be gimbal locking causing slight extra rotation. But probably not that big of a deal because you have the pivot node.

I think one solution to that is adding another node between the pivot and camera.

Okay, thank you so much for helping me, please tell me when you have a fix

``````func look(rel_mouse_pos:Vector2):
#rotate x axis up and down
rotate_object_local(Vector3.LEFT,rel_mouse_pos.y * speed)

#clamp rotation if y basis is pointing below the horizon
if transform.basis.y.y < 0.0:
# z basis tells us if we are pointed up or down
self.rotation.x = -PI/2.0 * sign(transform.basis.z.y)

# y rotation for left right
rotate_y(-rel_mouse_pos.x * speed)
``````

This isnt a fix, but just an example of of using basis vectors for rotation checks.

I think if you used `rotate_object_local` you could avoid the gimbal lock sitation as this would ignore the z axis bob.

if you wanted to add a limit similar to 85 degrees you can replace PI/2.0 (90 degrees) with your limit.

is that a replacement for my clamp code? if so, how do i implement it? and does that fix it or atleast makes thing any easier

since you say it works with the bob disabled, I would try the rotate_object_local function. in your unhanded input like so

``````camera.rotate_object_local(Vector3.LEFT, -event.relative.y * SENSITIVITY)
``````

Try this first

(I made some claims about rotations, it seems like they can go negative, and it is split on the simi-circle of pi; the range is ( -pi, pi ) and then it rolls over. so the clamp code is okay)

1 Like

That seems to make things a bit better, however, if i force my mouse up or down, it glitches and even spins while mousing straight up, and the controls become a buggy mess, directions randomize everytime you aim up… but atleast the headbob doesnt glitch the camera clamp anymore, yay

So I tried pulling in your code, and I noticed an issue with the clamp behavior.

Its kind of weird, basically the x axis rotation’s range is only from -pi/2 to pi/2, and you have a small area to clamp (5 degrees ). It is very easy to move past the clamp region with a high sensitivity. and this happens for me regardless if the bob is active. I think if you moved to the basis-vector based clamp it should solve that issue. at least make it harder since it would require a mouse movement of a whole (+180 degrees).

I would replaice this code

``````camera.rotation.x = clamp(camera.rotation.x, deg_to_rad(-85), deg_to_rad(85))
``````

with this

``````if camera.transform.basis.y.y < 0.0:
``````

that didn’t work out either, damn this is difficult.
now it still makes that flicking and headbob glitches it too

sorry i made a mistake it should be this above

the 0.08715574 is basically `sin(deg_to_rad(5))`, for 5 degrees.

any way it seems to work for me…

``````func _unhandled_input(event):
if event is InputEventMouseMotion:
pivot.rotate_y(-event.relative.x * SENSITIVITY)
camera.rotate_object_local(Vector3.LEFT, -event.relative.y * SENSITIVITY)
if camera.transform.basis.y.y < 0.08715574: