3

With the Unity 5.1 and Oculus SDK 0.6 and the new built-in Virtual Reality Supported check-box, I cannot seem to change the camera's position in VR.

Of course I can change the camera's Tranform Position component numbers (i.e. x and y and z) but when I run in play mode, it becomes obvious that Oculus' seeing camera has not moved.

How do I move/change the Oculus' perspective, to adjust how the Unity world is seen through the 2 lenses?

2 Answers2

4

Add a parent GameObject to the camera and move that one, don't modify the VR camera.

Krzysztof Bociurko
  • 4,575
  • 2
  • 26
  • 44
  • Thanks ChanibaL. Is the `Main Camera` that comes with every new project the same as the camera that Oculus uses, when you check the `Virtual Reality Supported` option? What do you mean by VR camera? Since the elimination of `OVR` prefabs, etc... I am confused what actually happens (e.g. camera wise) when you tick the Unity VR box. Can you please explain this a bit? Thx –  Aug 19 '15 at 06:52
  • 2
    Pretty much the same thing happens as with the `OVRCamera` prefab, only you have no control over it in the editor. Shame, really. Not sure if there are runtime added game objects in a simmilar hierarhy (a camera for each eye etc). Look at [the official docs](http://docs.unity3d.com/Manual/VROverview.html) if you haven't already. – Krzysztof Bociurko Aug 19 '15 at 12:17
2

Expanding on Krzysztof's answer, I usually use something like this (I attach this component to the VR Camera, give it an empty game object as a parent, then set that game object to be the vrCameraHolder):

[RequireComponent(typeof(Camera))]
public class VRPlayer : MonoBehaviour
{
    // set to be the parent of this object
    public Transform vrCameraHolder;

    // simple utility functions
    public static Quaternion LocalToWorldRotation(Transform t, Quaternion localRot)
    {
        return t.rotation * localRot;
    }
    public static Quaternion WorldToLocalRotation(Transform t, Quaternion rot)
    {
        return Quaternion.Inverse(t.rotation) * rot;
    }

    // Gets the body part position in world space
    public Vector3 GetBodyPartPosition(UnityEngine.XR.XRNode bodyPart)
    {
        return vrCameraHolder.localToWorldMatrix.MultiplyPoint(UnityEngine.XR.InputTracking.GetLocalPosition(bodyPart));
    }

    // Gets the body part rotation in world space
    public Quaternion GetBodyPartRotation(UnityEngine.XR.XRNode bodyPart)
    {
        return LocalToWorldRotation(vrCameraHolder, UnityEngine.XR.InputTracking.GetLocalRotation(bodyPart));
    }

    // moves entire player body so that this becomes true
    public void SetBodyPartPosition(UnityEngine.XR.XRNode bodyPart, Vector3 pos)
    {
        Vector3 bodyPartPos = vrCameraHolder.localToWorldMatrix.MultiplyPoint(UnityEngine.XR.InputTracking.GetLocalPosition(bodyPart));
        vrCameraHolder.position += pos - bodyPartPos;
    }


    // if you want to change rotation you should probably only use this to keep the headset tilted the same way (y axis is up, so 0 is forward along x axis, 180 is backwards along x axis, 90 and 270 are along z axis, etc.)
    public void SetBodyPartYRotation(UnityEngine.XR.XRNode bodyPart, float yRot)
    {
        Vector3 curRot = GetBodyPartRotation(bodyPart).eulerAngles;
        SetBodyPartRotation(bodyPart, new Vector3(curRot.x, yRot, curRot.z));
    }

    // rotates entire player body so that this becomes true (but doesn't change position)
    public void SetBodyPartRotation(UnityEngine.XR.XRNode bodyPart, Quaternion rot)
    {
        Quaternion curWorldRot = GetBodyPartRotation(bodyPart);
        Quaternion cancelOutWorldRot = Quaternion.Inverse(curWorldRot);
        float angle1;
        Vector3 axis1;
        cancelOutWorldRot.ToAngleAxis(out angle1, out axis1);
        Vector3 bodyPartPosition = GetBodyPartPosition(bodyPart);
        vrCameraHolder.RotateAround(bodyPartPosition, axis1, angle1);
        // now player rotation = not rotated
        float angle2;
        Vector3 axis2;
        rot.ToAngleAxis(out angle2, out axis2);
        vrCameraHolder.RotateAround(bodyPartPosition, axis2, angle2);
    }

    // rotates entire player body so that this becomes true (but doesn't change position)
    public void SetBodyPartRotation(UnityEngine.XR.XRNode bodyPart, Vector3 eulerAngles)
    {
        SetBodyPartRotation(bodyPart, Quaternion.Euler(eulerAngles));
    }
}
Phylliida
  • 4,217
  • 3
  • 22
  • 34