- Home /
Why does my camera automatically flip when trying to follow object around X-axis?
I'm really hoping someone can help me with this. My basic problem is that I have a camera following a ship. The ship can rotate 360 degrees around the X and Y axis. I was using the default SmoothFollow script for the camera, which works great for rotation around the Y axis, but as designed does not rotate around X. So, I tried to adjust it to work similarly around the X axis. However, what happens is once the ship rotates past 90 degrees up or down, the camera following it automatically flips around and everything is messed up. I'm sure this has to do with quaternions, which I still don't comprehend well, since I see in the inspector the camera rotation starts changing in all 3 planes all of a sudden. Here is the adjusted code I'm using and here is a site demonstrating the problem, since that shows it much better than words. Rotate around using the arrow keys, and wasd. Press just up or down arrows and you'll easily see the problem: Click to see the problem!
var target : Transform; var distance = 10.0;
var height = 5.0;
var heightDamping = 2.0; var rotationDamping = 3.0;
private var wantedRotationAngleY:float;
// Place the script in the Camera-Control group in the component menu @script AddComponentMenu("Camera-Control/Smooth Follow")
function LateUpdate () { // Early out if we don't have a target if (!target) return;
// Calculate the current rotation angles wantedRotationAngleY = target.eulerAngles.y; wantedRotationAngleX = target.eulerAngles.x; wantedRotationAngleZ = target.eulerAngles.z;
//wantedHeight = target.position.y + height;
currentRotationAngleY = transform.eulerAngles.y;
currentRotationAngleX = transform.eulerAngles.x;
currentRotationAngleZ = transform.eulerAngles.z;
//currentHeight = transform.position.y;
// Damp the rotation around the y-axis currentRotationAngleY = Mathf.LerpAngle (currentRotationAngleY, wantedRotationAngleY, rotationDamping Time.deltaTime); currentRotationAngleX = Mathf.LerpAngle (currentRotationAngleX, wantedRotationAngleX, rotationDamping Time.deltaTime); currentRotationAngleZ = Mathf.LerpAngle (currentRotationAngleZ, wantedRotationAngleZ, rotationDamping * Time.deltaTime);
// Damp the height //currentHeight = Mathf.Lerp (currentHeight, wantedHeight, heightDamping * Time.deltaTime);
// Convert the angle into a rotation currentRotation = Quaternion.Euler (currentRotationAngleX, currentRotationAngleY, currentRotationAngleZ);
// distance meters behind the target transform.position = target.position; transform.position -= currentRotation Vector3.forward distance;
// Always look at the target transform.LookAt (target); }
Thanks in advance for any help.
Answer by user-5298 (google) · Oct 21, 2010 at 12:35 AM
Just to answer this question myself in case anyone comes across a similar problem. The solution in my case was to keep all my rotation manipulation using quaternions. I 'think' using euler angles like I did introduced gimbal lock, which caused my issues. Once I removed those and did it all using quaternion, the problem was solved.
Here's the code:
// The target we are following var target : Transform; // The distance in the x-z plane to the target var distance = 2.0; // the height we want the camera to be above the target var height = 5.0; // How much we var heightDamping = 2.0; var rotationDamping = 3.0;
private var oldRotation:Quaternion; private var targetRotation:Quaternion;
function Start () { oldRotation = target.rotation; }
function LateUpdate () { // Early out if we don't have a target if (!target) return;
targetRotation = target.rotation; currentRotation = Quaternion.Lerp (oldRotation, targetRotation, rotationDamping Time.deltaTime); oldRotation = currentRotation; transform.position = target.position; transform.position -= currentRotation Vector3.forward * distance; transform.LookAt(target, target.TransformDirection(Vector3.up));
}
I know this is a bit old, but is still valid.
just wanted to add that in order to "adjust" height, simply add the following before the final "LookAt" transform:
transform.position += currentRotation * Vector3.Up * height;
oh also, if you place this into "fixedupdate" ins$$anonymous$$d of lateupdate, it will resolve jitters.
Hi, I just had the same problem and I used your script and it AL$$anonymous$$OST solved the problem, but there is one issue with your script. When the ship rolls to left or right, the camera also rolls to left and right, which is not what I want. How can I eli$$anonymous$$ate the rolling part?
Your answer
Follow this Question
Related Questions
A little help with this camera script please? 3 Answers
Lerp Third Person Camera Rotation 1 Answer
Camera rotation script logic error? 0 Answers
Rotation, my script shouldn't work but does. 0 Answers
camera rotation apparent to player 1 Answer