Camera Tracking in Unity

Hello all,
I want to camera track a movie to be able to put some 3d objects on top of it, so:
1 - I did the camera tracking with Boujou (quite old but still good) - everything is OK
2 - I’ve imported my Boujou camera in 3dsmax and checked with the background video - everything is OK
3 - I’ve exported and then imported the camera (as a dummy) in Unity as fbx
4 - for test, I’ve linked a Unity Camera and my background video to this dummy - everything is OK

Now the hardest part:
Since Unity Camera and my background video should stay at 0,0,0, I wrote a script to transform everything in the opposite direction: basically this script take position and rotation from the imported dummy and first move my GameObject (that contains my 3d objects) in the opposite direction, and next rotate the parent pivot of my GameObject (located at 0,0,0) in the opposite direction.
This is my script

//I attach this script to the GameObject that I want to move and rotate
//so to match the animation of the imported camera

using UnityEngine;

public class RestoreBillboardsPositionFromCamera : MonoBehaviour {

    public GameObject cameraToTrack; //this is the animated dummy imported from 3dsmax
    private GameObject pivot; //this is the parent pivot of my Gameobject, that I use only for rotation
    private Quaternion newRotation;

    private float initialPosX;
    private float initialPosY;
    private float initialPosZ;


    // Use this for initialization
    void Start () {
        initialPosX = cameraToTrack.transform.position.x;
        initialPosY = cameraToTrack.transform.position.y;
        initialPosZ = cameraToTrack.transform.position.z;

        pivot = gameObject.transform.parent.gameObject;
    }

    void Update () {
        //Here I translate my GameObject
        gameObject.transform.localPosition = new Vector3 (-1* (cameraToTrack.transform.position.x - initialPosX), -1* (cameraToTrack.transform.position.y - initialPosY), -1* (cameraToTrack.transform.position.z - initialPosZ));

        //Here I rotate the parent pivot of the GameObject
        newRotation.eulerAngles = new Vector3(cameraToTrack.transform.eulerAngles.z, cameraToTrack.transform.eulerAngles.y, cameraToTrack.transform.eulerAngles.x);
        newRotation = Quaternion.Inverse (newRotation); //here I invert the rotation
        newRotation *= Quaternion.Euler (0, 90, 0); //I need this because otherwise it would be rotated 90 degrees but I don't know why since this GameObject that I'm using as test is imported from 3dsmax as well, and it has the same pivot as the imported camera
        pivot.transform.rotation = newRotation;
    }
}

(I had to swap X and Z axis for rotation due to different coordinate system from 3dsmax and Unity).
Now my issue is that my 3d objects are no more so well aligned to the background video anymore:
while on the Y rotation it seem I have no problems, on the other axis it’s a bit wrong.
I think that it could be a matter of Quaternion rotation but I really don’t know how to fix it.

Here are some pics to try to better explain:
in GREEN is my test GameObject, that does not move while the Unity Camera and the backgound are moving because parented to the imported animated dummy from 3dsmax. - This is OK!
In RED is my test GameObject, with this script attached, that move while the Unity Camera and the background stay in place. - This is WRONG!


If I don’t swap X and Z axis like I do at line 31 of the code the result is totally wrong, so I think that the problem should be somewhere else…
Any help will be much appreciated!
Many thanks!

just solved!
To do this screenshots helped me a lot to understand the isssue.
I had to multiply by -1 the Z axis
here the final script

using UnityEngine;

public class RestoreBillboardsPositionFromCamera : MonoBehaviour {

    public GameObject cameraToTrack; //this is the animated dummy imported from 3dsmax
    private GameObject pivot; //this is the parent pivot of my Gameobject, that I use only for rotation
    private Quaternion newRotation;

    private float initialPosX;
    private float initialPosY;
    private float initialPosZ;


    // Use this for initialization
    void Start () {
        initialPosX = cameraToTrack.transform.position.x;
        initialPosY = cameraToTrack.transform.position.y;
        initialPosZ = cameraToTrack.transform.position.z;

        pivot = gameObject.transform.parent.gameObject;
    }

    void Update () {
        //Here I translate my Gamobject
        gameObject.transform.localPosition = new Vector3 (-1* (cameraToTrack.transform.position.x - initialPosX), -1* (cameraToTrack.transform.position.y - initialPosY), -1* (cameraToTrack.transform.position.z - initialPosZ));

        //Here I rotate the pivot
        newRotation.eulerAngles = new Vector3(cameraToTrack.transform.eulerAngles.z, cameraToTrack.transform.eulerAngles.y, -1 * cameraToTrack.transform.eulerAngles.x);
        newRotation = Quaternion.Inverse (newRotation);
        newRotation *= Quaternion.Euler (0, 90, 0);
        pivot.transform.rotation = newRotation;
    }
}
4 Likes