Skip to main content
Up and Coming
December 17, 2014

How to limit the track position movement (Oculus - Unity)

Hi everybody,

Question:
I would like to limit the head tracking movement of the Oculus Rift in Unity to a region.
The aim is that the player keeps his head on his shoulders all time.
I am wondering if someone already have code (or work) on this ?
And if you guys have links to help me do that :geek: .

RaymanExemple.PNG

    6 replies

    EloiStreeAuthor
    Up and Coming
    December 19, 2014
    Hi everybody :) ,
    I pose this answer in aim to know if what I am doing is shit and if you guys have a better solution :geek: .


    Here is the solution I found:
    (Codes under Beerware license)
    In OVRCameraRig.cs, I change the UpdateAnchors() methode by the following code :
    - delegatePositionning : give the possibility to manage the positionning instead of OVRCameraRig.
    - onPositionningUpdate: send to delegate the data that should be use to position the OVR cameras.

     public bool delegatePositionning;
    public delegate void UpdatePositionning(OVRPose leftPose, OVRPose rightPose, Transform left, Transform center, Transform right);
    public UpdatePositionning onPositionningUpdate;

    private void UpdateAnchors()
    {

    if (! delegatePositionning)
    {

    OVRPose leftEye = OVRManager.display.GetEyePose(OVREye.Left);
    OVRPose rightEye = OVRManager.display.GetEyePose(OVREye.Right);
    leftEyeAnchor.localRotation = leftEye.orientation;
    centerEyeAnchor.localRotation = leftEye.orientation; // using left eye for now
    rightEyeAnchor.localRotation = rightEye.orientation;

    leftEyeAnchor.localPosition = leftEye.position;
    centerEyeAnchor.localPosition = 0.5f * (leftEye.position + rightEye.position);
    rightEyeAnchor.localPosition = rightEye.position;
    }
    else
    {
    if (onPositionningUpdate != null)
    {
    OVRPose leftEye = OVRManager.display.GetEyePose(OVREye.Left);
    OVRPose rightEye = OVRManager.display.GetEyePose(OVREye.Right);
    onPositionningUpdate(leftEye, rightEye, leftEyeAnchor, centerEyeAnchor, rightEyeAnchor);
    }
    }
    }




    Now that I can manage the positionning instead the OVRCam with the original data.
    I can do what I want with it ;) .


    using UnityEngine;
    using System.Collections;

    [RequireComponent(typeof(OVRCameraRig))]
    public abstract class MyOVR_Positionning : MonoBehaviour
    {


    private OVRCameraRig cameraRig;
    public Transform root;
    public void OnEnable()
    {
    if (cameraRig == null)
    {
    cameraRig = GetComponent<OVRCameraRig>() as OVRCameraRig;
    }
    if (cameraRig != null)
    {
    cameraRig.onPositionningUpdate += PositionOculusInScene;
    }

    }

    public void OnDisable()
    {
    if (cameraRig != null)
    {
    cameraRig.onPositionningUpdate -= PositionOculusInScene;
    }

    }


    // Methode to inherit to be able to repositionning the camera at will.
    protected abstract void PositionOculusInScene(OVRPose leftPose, OVRPose rightPose, Transform left, Transform center, Transform right);

    // Methode to apply the position you wantnow like they do in OVRCamera
    protected void ApplyPositionningAt(Transform leftOVREye, Transform OVRcenter, Transform rightOVREye, ref Vector3 centerPosition, ref Vector3 toGoToTheRight, ref Vector3 toGoToTheLeft, ref Quaternion orientationLeft, ref Quaternion orientationRight)
    {
    leftOVREye.localPosition = centerPosition + toGoToTheLeft;
    OVRcenter.localPosition = centerPosition;
    rightOVREye.localPosition = centerPosition + toGoToTheRight;

    leftOVREye.localRotation = orientationLeft;
    OVRcenter.localRotation = orientationLeft;
    rightOVREye.localRotation = orientationRight;
    }
    }


    For exemple: limitate the head position, multiply it distance ...


    using UnityEngine;
    using System.Collections;

    public class MyOVR_StayNextNeck : MyOVR_Positionning {


    public Vector3 offsetbaseAdjustment;


    public float decreaseDistance = 0.3f;
    public float maxDistance = 0.5f;

    protected override void PositionOculusInScene(OVRPose leftPose, OVRPose rightPose, Transform left, Transform center, Transform right)
    {
    if (left == null || center == null || right == null) return;
    if (root == null)
    {
    Debug.Log("No root define !", this.gameObject);
    }
    Vector3 centerPosition = (leftPose.position + rightPose.position) / 2f;
    Vector3 centerToRight = rightPose.position - centerPosition;
    Vector3 centerToLeft = leftPose.position - centerPosition;

    //Add to the center the offset wanted.
    // How many distane between the offset and the center
    float rootDistance = Vector3.Distance(Vector3.zero, centerPosition);

    if (rootDistance > decreaseDistance)
    {
    float distLimit = maxDistance - decreaseDistance;
    float pourcentBeforeOutMax = Mathf.Clamp((rootDistance - decreaseDistance) / (maxDistance - decreaseDistance), 0f, Mathf.Infinity);
    float pourcentToCourbe = pourcentBeforeOutMax * 0.5f * 0.5f;
    centerPosition = offsetbaseAdjustment + centerPosition.normalized * (decreaseDistance + decreaseDistance * pourcentToCourbe);

    }
    else
    centerPosition = offsetbaseAdjustment + centerPosition;

    ApplyPositionningAt(left, center, right, ref centerPosition, ref centerToRight, ref centerToLeft, ref leftPose.orientation, ref rightPose.orientation);

    }


    }
    Participant
    March 5, 2017

    I realize that this is an old thread.. but I am interested to know if this worked and how well. I am needing  to limit the head tracking to prevent the player from popping the camera through walls and exploiting the game.


    March 6, 2017
    Hmm. Limiting a player's ability to freely move his or her head can be jarring. An alternative solution that doesn't restrict the player's natural head movement could be to detect the clipping and fade the display until the player moves his/her head out of the wall.
    Participant
    March 7, 2017
    Thanks Metro... I am not trying to limit the players ability to freely move his head. I am trying to reduce the tracking footprint. The OVR manager has an option to turn tracking off completely which is nauseating as the world moves with the head awkwardly. My issue is that any time I stand next to a wall the OVRcamera can be moved to far by leaning or standing up and walking. If I enlarge the players collision capsule to match the tracking footprint it eliminates the issue, but also requires a massive buffer zone around ever object which is unacceptable. 

    I am not interested in fading the screen to black when the players head passes through collision. The screen would be constantly fading in and out.

    Anyway, if there is a place to reduce the OVRtracker's footprint I'd love to know where that is, and give it a try.

    Thanks!
    -Kory

    Inspiring
    March 10, 2017
    If the player's head is going to be "out of bounds" so much that the screen would be "constantly fading in and out," you're not going to make things any better by disabling tracking. Instead of annoying the player, you'll make them instantly nauseous. I think you need to rethink what you're trying to accomplish here... 

    Edit: to clarify what I mean, "limiting" the tracking sounds like it means "disabling it outside of a certain range." This will feel at least as nauseating to the player as the completely disabled tracking you've already tried. 
    March 14, 2017
    @negatronix What I did is to offset CameraRig.transform.localPosition to cancel the change in centerEyeAnchor.localPosition if the movement is beyond a threshold. However, as the head outside the valid region, any translation of the head makes the movement very awkward and nauseous. 

    Originally I thought limiting 
    centerEyeAnchor.localPosition should be enough, but for some reason that doesn't have any affect on positional tracking.