• Godot Help
  • Why is clamp being ignored after enough mouse motion?

Lethn I took your code and simplified it to just the mouse look component and I could not get it to print anything out of the range of -.75 to .75 regardless of how fast i moved my mouse:

extends CharacterBody3D

var mouseSensitivity = 0.2
var direction = Vector3()
var gravityVector = Vector3()
var horizontalVelocity = Vector3()
var movement = Vector3()
var customVelocity = Vector3()
var fall = Vector3()
var speed
var defaultMoveSpeed = 5.0
var sprintMoveSpeed = 10.0
var crouchMoveSpeed = 1.0
var gravity = 10
var jumpHeight = 6
var horizontalAcceleration = 6

var swayAmount = 30
var verticalSwayAmount = 30

var plasmaPistolMaxGunShake = 1.5
var crouchingPlasmaPistolMaxGunShake = 0.5

@onready var mouseLookNode = $MouseLookNode
@onready var playerCollisionShape = $PlayerCollisionShape
@onready var playerCamera = $MouseLookNode/PlayerCamera




var isHittingCeiling = false
var isCrouching = false
var isSprinting = false
var isPlayerFiring = false
var isFlashlightEnabled = false

var canEnterDriverSeat = false
var vehicleDriverArea

func _ready():
	Input.set_mouse_mode(Input.MOUSE_MODE_CAPTURED)
	playerCamera.make_current()
	isCrouching = false
	playerCollisionShape.set_deferred(("disabled"), false)
	speed = defaultMoveSpeed
	

func _unhandled_input(event):
	if event is InputEventMouseMotion:
		rotate_y(deg_to_rad(-event.relative.x * mouseSensitivity))
		
		mouseLookNode.rotate_x(deg_to_rad(mouseSensitivity * event.relative.y))
		mouseLookNode.rotation.x = clamp (mouseLookNode.rotation.x, -(PI/4), PI/4)
		prints(mouseLookNode.rotation.x);
#		mouseLookNode.rotation.x = clamp(mouseLookNode.rotation.x, deg_to_rad(-80), deg_to_rad(80))

```		

That's really interesting, I wonder if there's something going on with the mouse in another part of the code then? I wonder what it could be, I should probably isolate sections with commenting in that case and try to find the exact cause.

Okay, for the record, I still managed to break the clamp even with this minimal example, what's interesting though about the way it breaks is the rotation borks and goes all wobbly when you're moving the mouse directly up and down, is this an example of some sort of gimbal lock happening possibly? Not sure what to make of it at all.

It might be easier if you could upload a zip of the project somewhere (or send it to one of us if you don't want it public yet) so we can see it happening live and debug it. I tried some of the code above (in Godot 3.5 and 4) and couldn't get it to fail. It seems like something elsewhere is affecting it after each clamp.

    I'm not sure what you're seeing. It seems pretty consistent here.

    You're not wiggling it enough 😃 you need to wiggle it vertically really. really fast. if that's you.

    It might be easier if you could upload a zip of the project somewhere (or send it to one of us if you don't want it public yet) so we can see it happening live and debug it. I tried some of the code above (in Godot 3.5 and 4) and couldn't get it to fail. It seems like something elsewhere is affecting it after each clamp.

    Kojack I'll upload a vid on my own channel so you can see what's happening, I don't mind sharing the player controller code but the project itself is not something I'm open sourcing.

      Lethn I can assure that I have no interest in anything other than making tiny gremlins walk around procedural terrain populated with crappy tree models, and I only have a middling interest in that.

      If you want my opinion, you have something else going on in your code. Code does what you tell it to, and i've never seen an instance where it decided to do something else. It's pretty unlikely that the clamp is your problem.

      In a pinch you can put some if(....x > abs(80degrees)) prints() messages in different places to debug this, or just put a breakpoint inside of that same if. You'll probably find that it is being affected somewhere else.

      I mean I agree, I just can't isolate what code could be causing it? Either way there's clearly something up with the rotation and it happens specifically when the mouse is wiggled vertically up and down enough, I'll use print and see what's going on a bit in more detail. The thing is I tried commenting out sections and the same thing happened on my end which is pretty odd.

      Lethn It's pretty clear that your "up" axis, or Y rotational basis is getting whacked somehow. I upped the camera sensitivity to .7 and went crazy on the mouse and still could not reproduce.

      But here's a fun bug with my gremlin getting caught on a tree leaf and having it's up axis get jacked up thanks to wonky collision:

      OH! I just thought of something extremely unlikely, could it possibly be my mouse's DPI? I'm going to have to test this.

      Edit: Nope nevermind, still managed it, I do wonder if it's a hardware issue though now I think about it, we need some testers lol.

        Lethn Is there any chance at all you're colliding with something? The point of my video was to show that collisions themselves can affect the Y access of the parent object and screw up the total rotation of the player (of which your camera is attached to). I don't know why shaking the camera like that would do that though.

        That's a good idea! I'll double check but I'm not sure how this could be the case, the camera and mouselook node shouldn't have colliders attached to them unless I've messed up somewhere so it could be a parenting issue? I'll do some poking at it and see what happens.

        That video looks like what would happen if the x and y rotations are both performed on the same node.
        For example I can recreate the rolling to the side if I change the code to:

        func _unhandled_input(event):
        	if event is InputEventMouseMotion:
        		rotate_y(deg_to_rad(-event.relative.x * mouseSensitivity))
        		
        		rotate_x(deg_to_rad(mouseSensitivity * event.relative.y))
        		rotation.x = clamp (rotation.x, -(PI/4), PI/4)

        so both x and y rotations happen to the character controller, instead of x to the mouselooknode and y to the controller.

        As long as the character controller only rotates around y and the mouselooknode only rotates around x, that shouldn't happen.
        I'd say try logging out the x,y,z rotations of the Player, MouseLookNode and PlayerCamera then look at what they are when the view is twisted. The Player should have 0 for the x and z, the MouseLookNode should be 0 for y and z, the PlayerCamera should be 0 for everything.
        (I wonder if something is rotating the camera, which is adding to the rotation of the mouse node)

        ...... You guys are going to love this, it turns out I had my mouse look node's y rotation set to -180 degrees and that's what was causing the clamp issues, I just didn't notice and @Kojack got it right with the MouseLookNode LOL. Amazing how basic things can screw up your code so royally if you haven't done the setup right, thank you, that issue was annoying me and being very baffling because there was nothing in the code I could see that could be doing it.

        Going to have to remember when dealing with my instances to make sure everything's defaulted to 0 before I started placing stuff in scenes. I'll try not to celebrate too soon and make sure to keep testing but holy hell that was frustrating.

        Edit: Yep, confirmed fix now it happens when I rotate the player itself in the scene too, so I need to rotate the scene if I want the player pointing the right way I think that's where I've been scewing up the rotations.

        There's a lot of oddities that can happen with rotations. 🙂
        I've seen some engines (or just euler angle classes) that when the pitch goes above 90 or below -90 it flips the entire system. So if you set it to 100 degrees pitched up, it would actually turn into 80 degrees up, 180 yaw (face backwards) and 180 roll (flip upside down). That meant you couldn't clamp a value to 90, because it never stored the larger value. In particular that can happen if the engine only gives you quaternions and you manually turn them back into angles.

        Gimbal lock is always so fun to debug, isn't it... /s

        10 months later

        I know it's pretty old topic, but me and my friend trying one of Lukky's Godot tutorials, from youtube. And he did camera rotation for 3rd person view, but without any rotation limit. I googled and found how to that with clamp, but quickly noticed that rotation become broken if I move mouse too fast vertically. Camera leans a bit, and Mathf.clamp stop working. I displayed rotations on a label, and noticed that Y axis changes after quick movements of mouse.
        I noticed that this happens only when I do:

                Vector3 camera_rot = camMount.Rotation;
                camera_rot.X = Mathf.Clamp(camMount.Rotation.X, Mathf.DegToRad(-70), Mathf.DegToRad(70));
                camMount.Rotation = camera_rot;

        So it's became broken, after I copy rotation to temp Vector3, change it, and then return values back to Rotation property.
        It's my first game engine that I try, and I barely coded anything complicated, before, or what's required actual math, so I'm really was confused why this happening. And I'm still confused.

        I was able to kinda fix it, by adding
        camera_rot.Y = Mathf.Pi;
        after clamp.
        Now reading this, I see that issue happens because -180deg rotation, and in that tutorial Player base node was rotated 180 Y (and, I guess, I rotated it to -180) , because coordinate system in Godot is different to that from Mixamo or something like that, I'm still not sure.
        So I've reset Player rotation to 0,0,0 from -180, and rotated camera to +180.
        And now it's not breaking even with craziest mouse moves.
        I really wish I able to understand what exactly goes wrong, but even after reading this thread I'm still not sure.

        5 months later

        Lethn it's not hardware cause I'm having the exact same problem. have you fixed it yet? if so please tell me how!

        • xyz replied to this.