I have a script for a MouseLook Third Person camera (think of it like a spaceship), while I’ve avoided gimbal lock I have this slight problem where the character or camera (its hard to tell which) are rotating along its “side” or rolling slightly after some combination of XY axis rotations.
Screen.lockCursor = lockCursor;
float horizontal = Input.GetAxis("Mouse X");
float vertical = Input.GetAxis("Mouse Y");
horizontal *= rotateSpeed;
vertical *= rotateSpeed;
target.transform.rotation *= Quaternion.Euler(-vertical, horizontal, 0);
transform.position = target.transform.position - (target.transform.rotation * offset);
myTarget = target.transform;
var relUp = myTarget.TransformDirection(Vector3.forward);
var relPos = myTarget.position - transform.position;
transform.rotation = Quaternion.LookRotation(relPos, relUp);
It would probably be fine perhaps to just reset the Z rotation to 0 maybe or is there a better way?
Hi, for this kind of camera code, it’s sometimes easier to have a hierarchy of 2 objects/Transform: each one assigned to the rotation around 1 axis only. The engine will then combine the rotations when computing Transforms.
Example: you have an object “Target” that you move (only position) as your camera target (= on the character or spaceship). Also, this “Target” will manage rotation around Y. So you can change it’s transform.rotation using Quaternion.Euler( 0, angle, 0 ).
You define a child object of “Target”, let’s say “Elevation”, that is positioned (0, 0, 0) relatively to it’s parent “Target”. Then, you can rotate this object on the X axis with Quaternion.Euler(angle, 0, 0) on transform.localRotation (note: local).
After rotating it, you can use Elevation.transform.back to get a transformed vector that combines the 2 rotations. Use Evelation.transform.back * offset to get the position of a camera. To get the angle of the camera, just use Elevation.transform.rotation (not local this time, it will “look at” Target). I guess there will be no gimbal lock here either but I didn’t tested it.
Edit: I didn’t try to code this, it might be more convenient to rotate the “Evelation” object around Z and use transform.right or .left to position the camera, depending on the init/0 values you want.