Help rotating object with camera rotation compensation?

Attached unity package [127855-rotationproject.zip|127855].

I am trying to copy the rotation of an object, ObjectA, onto another object, ObjectB. ObjectB is parented to the Main Camera. ObjectA is simulating a controller. When ObjectA is rotated, ObjectB is rotated. However, when the camera itself rotates the calculation is no longer correct. The yaw (turning on green x-axis) always works perfectly but the pitch and roll switch between the blue y-axis and the red x-axis dependent upon which direction the Main Camera is facing. Whats going wrong with the calculation?

using UnityEngine;

public class CubeRotation : MonoBehaviour {

    // Var declaration
    private Camera cam;
    public Transform controlCube;

    // Use this for initialization
    void Start()
    {
        cam = Camera.main.GetComponent<Camera>();
    }

    // Update is called once per frame
    void Update()
    {
        transform.rotation =
            (controlCube.rotation * cam.transform.rotation)
            * Quaternion.Inverse(cam.transform.rotation);
    }
}

Not sure I understand the question, but I’ll try to give both options.


Option 1 - you want the rotation of the cube to be exactly like the control, in absolute terms (ie if someone looked at both of them, they would see the same rotation. For that, it’s as simple as setting the eulerAngles to be that of the control cube, no calculation needed, since eulerAngles is already in world position (can also set the rotation since it’s also in world space):

    transform.eulerAngles = controlCube.eulerAngles

Option 2 - you want the rotation of the cube relative to the camera, to be the rotation of the controlCube in absolute terms. So if the controlCube is facing up, the cube will face towards the camera’s up. So if the camera would be looking down, it’s “up” would be the world forward, so the cube would face forward and appear as facing up to the camera. In this case, it’s as easy as setting the localEuler of the cube to be the world euler of the control cube (so the direction of the cube relative to the camera is the absolute direction of the control cube):

    transform.localEulerAngles = controlCube.eulerAngles

If you meant something else, please explain with an example.

var temp = (controlCube.rotation * cam.transform.rotation)
* Quaternion.Inverse(cam.transform.rotation);

var newQuat = new Quaternion();
newQuat.x = temp.z;
newQuat.y = temp.y;
newQuat.z = -temp.x;
newQuat.w = temp.w;

transform.rotation = newQuat;