I had this issue months ago and I solved it after weeks of trial and error, using: transform.eulerAngles = new Vector3(xRotation, player.rotation.eulerAngles.y, 0f);
30ne3j
But now I had to update my code to get other mouse input functionality to work so I had to get rid of that line, and now I have that old problem again which I did not think would even occur with my new mouse movement code.
I changed my code to Quaternion.AngleAxis and transform.localRotation:
var xQuat = Quaternion.AngleAxis(rotation.x, Vector3.up);
var yQuat = Quaternion.AngleAxis(rotation.y, Vector3.left);
transform.localRotation = yQuat;
player.transform.localRotation = xQuat;
But I thought using AngleAxis in the way I am was supposed to remove any potential gimbal lock? I’m not sure what to do here without breaking my code.
You’ll never get gimbal lock from such a limited range of motion. It’s only if you wanted your character to be able to turn upside down and roll left and right would you start to run into gimbal lock problems.
Your code looks fine. Are you doing any clamping to the rotation values? That’s more likely to be the cause of your problem. Show us the whole mouse look script.
Yeah that’s what my first thought was. I don’t do anything unusual with clamping, just the standard vertical 90f -90f clamp.
Another issue that I didn’t show because I didn’t want to spam videos, if the rotating object is rotating on the x or z axis, my camera will match its rotation, but maybe it is all happening because my camera is a child of my player.
float yRotationLimit =90f;
Vector2 mouseDelta = Input.GetAxis(xAxis) * Vector2.right + Input.GetAxis(yAxis) * Vector2.up;
rotation.x += mouseDelta.x * sensitivity;
rotation.y += mouseDelta.y * sensitivity;
rotation.y = Mathf.Clamp(rotation.y, -yRotationLimit, yRotationLimit);
var yQuat = Quaternion.AngleAxis(rotation.y, Vector3.left);
var xQuat = Quaternion.AngleAxis(rotation.x, Vector3.up);
// rotation.x = xQuat.eulerAngles.y; // this line I added as a test to see if it helped
transform.localRotation = yQuat;
player.transform.localRotation = xQuat;
Unfortunately that didn’t help. I checked my Parent script and it’s empty so there’s no overlapping code and I commented out every other part of my mouse movement script just to be sure but yeah.
I also just tried two very weird approaches, one was to have an else statement that included player.eulerAngles.rotation.y just like in the old solution of mine that I mentioned in my post and my second attempt was I created a temporary script which also contained player.eulerAngles.rotation.y, and then I would disable & enable my two scripts based on whether or not I was parented.
Both have the same end result with the “snap”.
Do I maybe split my player and camera? Isn’t there something you can do which prevents a child from also being parented? So in my mind when my player gets parented, my camera remains unparented and then I am able to free look with no snap. I just forgot what the process for that is
I think the next thing to look into is what’s happening when you step onto that platform?. Does the platform have a trigger that makes your player a child of the platform?
Yeah it does. My player becomes a child of that platform with a simple Player.transform.parent = transform; which then turns null once the player steps off it.
There’s also a rigidbody attached to the parent object with is kinematic on.
Damn I feel so dumb. I literally changed that line and the one before from localRotation to rotation, but I knew it felt weird me changing both but I just skipped past it not knowing that I should have just changed the actual player rotation from localRotation to rotation.
Thanks a lot for spotting the problem. From what I just tested briefly now, the issues I was having are gone, it works exactly how my old solution did.