Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Question rig position very high in virtual desktop

Discussion in 'XR Interaction Toolkit and Input' started by TzuriTeshuba, Feb 4, 2023.

  1. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    it seems when I play my build on Quest 2 through the "Virtual Desktop" app, my rig is like 10 units higher than when i play via oculus link. Anyone familiar with the issue? i am using XR Interaction toolkit with OpenXR, on an Oculus Quest 2 device.
     
  2. nilagard

    nilagard

    Joined:
    Jan 13, 2017
    Posts:
    77
    Try making a script that manually sets the starting Y position you wish to use when booting up your game, no matter which device / mode is being used.
     
    TzuriTeshuba likes this.
  3. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    yea i might just do that, thought maybe it was a known issue with a out of the box solution. just wondering, is that what you do? have a script for forcing the position? also did you experience what i mentioned on virtual desktop (and not on regular oculus link)?
     
  4. nilagard

    nilagard

    Joined:
    Jan 13, 2017
    Posts:
    77
    Without haven't seen your issue in a video, I think I experienced the same fault a few days ago aswell. Whenever I was in "Oculus mode" and went back to play my game after I woke the headset again I would appear higher up than what I did when I took my headset off. Annoying bug
     
    TzuriTeshuba likes this.
  5. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    thanks, ill try to get a video up here at some point when i use virtual desktop again(at least for future people stumbling on this post).
    One last question, I wrote a script to set the xr rig position as you suggested, and it works perfectly. Only issue i have is detecting when to call my EnsureXRRigIsProperlyPositioned() function. about 80% of the time, caling it on start does the job, but the other 20% it looks like some preconditions weren't met (like xr input or runtime related things). is there an event i could hook into? i spent hours looking and came up with nothing. i see that the xr rig's camera's position is constant for a couple of frames sometimes before it seems to jump into place. I tried different origin trackings as well.. no help :(
     
  6. nilagard

    nilagard

    Joined:
    Jan 13, 2017
    Posts:
    77
    TzuriTeshuba likes this.
  7. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    Thank you, really appreciate it!
     
  8. TzuriTeshuba

    TzuriTeshuba

    Joined:
    Aug 6, 2019
    Posts:
    185
    here is my solution for anyone stumbling on this thread. I initially relied on triggerring events based on user presence, but im not sure i need it, so its commented out. I found that i just need to trigger my ResetRigOrientation() logic one frame after i instantiate the XRRig. Also, if your use case is similar to mine, you dont really need to reference the userPresence at all. if you do use it, the input action reference is from the XR interaction toolkit samples hmd/UserPresence and you should tick the checkbox there for "Initial state check".

    the code could be simplified i know, like the "eyes" field could be xrRig.cameraGameObject.transform, and the action.canceled event hooks are probably not necesary.

    Code (CSharp):
    1. using System;
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using UnityEngine.InputSystem;
    6. using UnityEngine.XR.Interaction.Toolkit;
    7.  
    8. //resets the position and rotation (about xr rigs local up axis) of the xr rig
    9. //such that {eyes} (the camera) is at relHeadPos in this's local space
    10. //and eye's forward is in this's local yz plane
    11. public class ResetRigOnPresence : MonoBehaviour
    12. {
    13.     [SerializeField] XRRig xRRig;
    14.     [SerializeField] Transform eyes;//the camera of the rig.
    15.     [SerializeField] Vector3 relHeadPos;//desired position of the rigs camera in this's local space
    16.     // [SerializeField] InputActionReference presenceIAR;
    17.  
    18.     private void Start() {
    19.         StartCoroutine(ResetWhenPresent());
    20.     }
    21.  
    22.     IEnumerator ResetWhenPresent(){
    23.         // while(presenceIAR.action.ReadValue<float>() < 0.5f){
    24.         //     yield return WaitCache.waitForEndOfFrame;
    25.         // }
    26.         yield return WaitCache.waitForEndOfFrame;
    27.         ResetRigOrientation();
    28.     }
    29.  
    30.     void OnEnable()
    31.     {
    32.         // presenceIAR.action.started += HandlePresenceChange;
    33.         // presenceIAR.action.canceled += HandlePresenceChange;
    34.     }
    35.  
    36.     void OnDisable()
    37.     {
    38.         // presenceIAR.action.started -= HandlePresenceChange;
    39.         // presenceIAR.action.canceled -= HandlePresenceChange;
    40.     }
    41.  
    42.     // private void HandlePresenceChange(InputAction.CallbackContext obj)
    43.     // {
    44.     //     bool isPresent = obj.ReadValueAsButton();
    45.     //     if(isPresent) ResetRigOrientation();
    46.     // }
    47.     public void ResetRigOrientation(){
    48.         Vector3 desiredHeadPos = this.transform.TransformPoint(relHeadPos);
    49.         Vector3 currHeadPos = eyes.transform.position;
    50.         Vector3 delta = desiredHeadPos - currHeadPos;
    51.         xRRig.transform.position += delta;
    52.        
    53.         Vector3 eyesFlatForward = Vector3.ProjectOnPlane(eyes.forward, this.transform.up);
    54.         float angleOffset = Vector3.SignedAngle(eyesFlatForward, this.transform.forward, this.transform.up);
    55.         xRRig.transform.Rotate(0f, angleOffset, 0f, Space.Self);
    56.     }
    57. }
     
  9. ericprovencher

    ericprovencher

    Unity Technologies

    Joined:
    Dec 17, 2020
    Posts:
    145
    Thanks for sharing your solution! I think a part of the issue is that, out of the box there’s a 1.36m offset on the camera offset in the origin rig when you set the origin to unspecified. This mode serves to fallback to device origin mode when “floor” isn’t supported (say on hololens).

    When the app starts that offset is zeroed out in floor mode.

    The issue is that OpenXR doesn’t actually support “floor” calibration mode, but stage calibration, which doesn’t receive floor centering events. We’re working on a workaround for this, but in the interim if you set your origin mode to device after the initial floor alignment, you will get the the entering events, and you should be able to capture the initial floor offset to apply against your device calibration.

    Since virtual desktop doesn’t actually support OpenXR, it might be that you’re running into different behavior here for this initial floor offset setting on both runtimes.
     
    TzuriTeshuba likes this.