# Trouble With Quaternions and orbital camera:

UPDATED: I have been trying to implement a Orbital Camera of sorts in a engine I am currently doing in Unity3D, the issue being I can't seem to do the correct rotation no matter what.

This is what it is needed:

Rotate on Y and X axis via the mouse, but the Y and X axis are not Vector.up or Vector.right they are given by the current Slope of the Target I am orbiting around.

I don't get how I can make it idependent of the character rotation, but at the same time dependent

This sorta works, but some loops have issues, check the video below for a taste of whats wrong

var forward = Vector3.forward; //Vector3.Cross(ViewTarget.transform.up, transform.right);
//Apply the rotation
var rot = Quaternion.AngleAxis(CurrentHorizontalLook, ViewTarget.transform.up);
var rot2 = Quaternion.AngleAxis(CurrentVerticalLook, transform.right) ;
Debug.DrawRay(ViewTarget.transform.position, Vector3.right * 5, Color.yellow, 0, false);
Debug.DrawRay(ViewTarget.transform.position, ViewTarget.transform.up * 5, Color.blue, 0, false);
var offset = forward * 5;
transform.rotation =  rot * rot2;
transform.position = ViewTarget.transform.position + EyeHeight + transform.rotation*-offset;
transform.LookAt(ViewTarget.transform.position, ViewTarget.transform.up);


EDIT : Maybe this image will help.

Black is the Up Vector, Red is the rotation on X Axis, Green is rotation on Y Axis. The trick here is it being idependent of the right and forward of the Target object , only the Up vector used to align the camera.

Edit: I have "something" that is somewhat related to what I want, but still missing one thing.

I got the camera to rotate correctly on the target Y axis, but it doesn't align to the ground plane at all.

Convention : Y = UP Z = Forward X = Right

var rot = Quaternion.AngleAxis(CurrentHorizontalLook, ViewTarget.transform.up);
transform.rotation = rot ;
var rot2 = Quaternion.AngleAxis(CurrentVerticalLook, transform.right) ;

transform.rotation =  rot * rot2;

var offset = forward * 5;


This is what I have , the issue now being that if the character is on a 90 degree wall the camera should be moving around the character on the same plane as the wall, but in my case it looks in a top down manner. If instead of WorldForward I used TargetForward it moves in the correct plane, but then when the character changes direction the camera shifts too.

I think a better explanation of what I want is this : I want the camera to rotate on the X,Z Plane of the character, and I want to be able to tilt it up or down in the Y,Z Plane. If you check the video I posted when Sonic goes in loop I want the camera to do sorta the same thing.

• I suggest adding some images to describe the problem. – concept3d Dec 4 '14 at 7:28
• Honestly I am not even sure what kind of images to add, what I am trying is to Orbit the camera around a point. See if the pictures I added help – Morphex Dec 4 '14 at 7:41
• Not sure, but maybe unity3dmmo.codeplex.com/discussions/245203 will help – tkausl Dec 4 '14 at 7:57
• @Morphex you need to at least know the normal of that point.. – concept3d Dec 4 '14 at 8:06
• I do know the normal, only the rotation itself I dont – Morphex Dec 4 '14 at 8:10

Assuming your camera have a independent forward vector that always points from position of camera to the character;

Suppose if you want to rotate the camera N radians in the local Y axis (character up) and maintains the same distance to target after the rotation:

quat = axisAngle(target.up, radian);
camera.forward = rotateByQuat(camera.forward, quat);
camera.side = normalized(cross(target.up, camera.forward));
camera.position = target.position - camera.forward * distanceToTarget.


Its easy to see that this does what you want regardless of the orientation of ground your character is standing on:

Whats missing from here is what to do when your character up change, ie, when he walks against a slope or wall. What you need to do here, is whenever the target up change, you need to set the camera up equal to character up again. But based on the difference between the new camera up and previous camera up, update the camera forward so that it is pointing to the character again (and of course, implicitly the position of camera since it is calculated from camera forward)

• It can't be Global up, it needs to be The Target up, because what happens when it is in slope? I want the camera to rotate in the plane that is tangent to the slope the character is on, my issue is that I can't use any of the character vectors except up, because if the character is moving "towards" the camera the forward vector is different than if it is moving "away" from the camera. And when he changes directions the camera would flip. I guess I want a camera similar to the zeldas games for nintendo, but being able to adjust to the slope the character is standing on. – Morphex Dec 6 '14 at 17:45
• Use target up instead and the forward as normalized(target.position - camera.pos); – user55564 Dec 6 '14 at 20:28
• I am either not understanding what you mean, or this is still not working as I want. – Morphex Dec 7 '14 at 4:43
• Which part is not working, the orientation of camera or position of camera? – user55564 Dec 7 '14 at 4:49
• The position mostly, when the character is in a wall, the camera forward is point in perpendicular fashion to the wall, it should be parallel. – Morphex Dec 7 '14 at 5:24