Search Unity

Question How do you implement OpenXR Focus Management in Unity 2020?

Discussion in 'VR' started by SpaceOwlGames, May 28, 2021.

  1. SpaceOwlGames

    SpaceOwlGames

    Joined:
    Apr 22, 2016
    Posts:
    61
    Hello,

    I am trying to implement the focus requirement for Oculus store submissions with OpenXR, there is a short overview of the states which look similar to OVR, but the sample code above makes zero sense to me. I was wondering if anyone already has done this and was able to share how to listen to these "session state change events".

    OpenXR Focus Management is described at the bottom of:
    https://developer.oculus.com/documentation/native/pc/dg-vr-focus/
    https://developer.oculus.com/documentation/native/pc/dg-dash
     
  2. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    400
    I think the unity openxr plugin handles all of this for you. The only one it doesn't is:

    • ShouldRecenter - XR_TYPE_EVENT_DATA_RECENTER_REQUESTED_OCULUS, enabled by the XR_OCULUS_recenter_event extension.

    If you find that you get rejected or can't hit the requirements, let us know and we'll investigate.
     
  3. SpaceOwlGames

    SpaceOwlGames

    Joined:
    Apr 22, 2016
    Posts:
    61
    I know right now players are reporting that attempting to close out of the game via the SteamVR or Oculus overlay does not work (the in-game exit button is fine), so it seems that "ShouldQuit" is not being triggered or perhaps received correctly. Could you let me know how to listen and catch these events? I've been looking for tutorial or code snippet examples but no one seems to know much about this at all. Would be much appreciated.
     
  4. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    We will need to look into this and get back to you.
     
  5. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    I tried this myself just now and I believe I see what you are seeing but want to clarify.

    I built and ran a standalone VR app using SteamVR OpenXR Runtime to play. The app loads but when I quit using the SteamVR menu the app closes within steam but on my desktop the app is still running but it seems it has been disconnected from VR. So you have to manually close that app to finish the exit process. Does that sound like what your users are seeing?

    We are looking into why this is happening now and once we have a fix we will let you know if there is or is not a work around until that fix is released.
     
  6. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I'm not sure about his issue, but that is an issue I am having.
     
  7. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    Ok we are on it, thanks.
     
  8. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    It looks like we already had a fix for this that is waiting for the next release. However in the mean time I wrote a simple feature that you could add to your project that will serve as a workaround until the next release of the OpenXR plugin. Create a file called
    ShutdownFeature.cs
    and paste this code in. Then in your OpenXR settings you should see a new feature called
    Shutdown Feature
    . Enable that feature and the app should now close when you shut down from within the steam or oculus menus.

    In general if you want to be closer to the OpenXR lifecycle you can use features to do this, which is what the workaround below is doing.

    Let me know if this works for you, thanks!

    Code (CSharp):
    1. using UnityEditor;
    2. using UnityEngine;
    3. using UnityEngine.XR.OpenXR.Features;
    4.  
    5. #if UNITY_EDITOR
    6. [UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Shutdown Feature",
    7.     BuildTargetGroups = new[] { BuildTargetGroup.WSA, BuildTargetGroup.Standalone, BuildTargetGroup.Android },
    8.     Company = "Unknown",
    9.     Desc = "Automatically shuts down the app when exit is requested.",
    10.     Version = "0.0.1",
    11.     FeatureId = featureId)]
    12. #endif
    13. public class ShutdownFeature : OpenXRFeature
    14. {
    15.     public const string featureId = "com.unknown.features.shutdown";
    16.  
    17.     protected override void OnSessionExiting(ulong xrSession)
    18.     {
    19.         base.OnSessionExiting(xrSession);
    20.  
    21.         Application.Quit();
    22.     }
    23. }
    24.  
     
    thep3000 likes this.
  9. SpaceOwlGames

    SpaceOwlGames

    Joined:
    Apr 22, 2016
    Posts:
    61
    @the_real_apoxol
    Thank you, this works.
    Can you expand on how features work or is there any doc on this?

    How would you expand this to trigger a function for a recenter request?

    I looked at OpenXRFeature parent class to see if there were other functions to override and found:
    Code (CSharp):
    1. protected override void OnSessionStateChange(int oldState, int newState) {
    2.         base.OnSessionStateChange(oldState, newState);
    3.         Debug.Log($"Session State Change {oldState} -> {newState}");
    4.     }
    Which seems to trigger when the headset startsup/wakes/put on, so that technically answers my original question.
    But if i could also catch the recenter request that would be useful.
     
  10. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467

    There is some documentation on features here:

    https://docs.unity3d.com/Packages/com.unity.xr.openxr@1.2/manual/features.html

    For the recenter request the way OpenXR handles that is the runtime will send the XrEventDataReferenceSpaceChangePending event to the application when the user triggers a recenter. We currently handle this internally within the OpenXR plugin but we could expose this up to the feature level to allow a feature to response to this request. Before we do that I would like to know more about what issue you are trying to solve with that callback? Is there something that the OpenXR plugin is not currently handling properly or just something you want to do custom?
     
  11. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    I copied over your work around and enabled in the OpenXR features. However, if I quit SteamVR from the desktop then it still does not exit the game. Quitting from within SteamVR doesn't exit it either. Any ideas?

    EDIT:
    Nevermind, I just noticed that the feature disabled itself somehow. I'll try enabling it again and see what happens.
     
  12. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    Ok let me know, quitting steam vr itself I did not try, possible in that situation the session exit event isnt received.
     
  13. emrys90

    emrys90

    Joined:
    Oct 14, 2013
    Posts:
    755
    Just retested and it seems to be working, thanks!
     
    the_real_apoxol likes this.
  14. SpaceOwlGames

    SpaceOwlGames

    Joined:
    Apr 22, 2016
    Posts:
    61
    @the_real_apoxol
    I just noticed that the "reset standing position" doesn't appear on the SteamVR overlay when in a Unity game.

    My setup:
    - Created new Unity Project 2020.3
    - Setup XR Manager with OpenXR 1.2.2
    - Setup default XR Rig + XRI Interaction Action Maps
    - Setup SteamVR to Standing Only

    - When the game is not running, bringing up the SteamVR overlay, the option to "Reset Standing Position" found in the lower right is present and works. Activating it will start a 3-sec countdown where it will then recenter + reorient you as expected.
    - When the game is played, bringing up the SteamVR overlay, the option no longer exists.
    - The option via the desktop window's hamburger menu is always present and works fine.

    Is SteamVR standing-only room setup being overridden by Unity?
     
    Last edited: Jun 8, 2021
  15. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    I dont think unity is overriding, but maybe it is not supported in OpenXR apps by steam? I will see if I see the same thing and if so see what valve says.
     
  16. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    The reset standing position button does seem to go away when running an OpenXR game on steam. You may want to report this to Valve as I dont think there is anything on our side that can be done. I will ping Valve as well to see if this is known.
     
  17. bendikorn

    bendikorn

    Joined:
    Sep 29, 2016
    Posts:
    6
    Is there anything else I would have to do to get it to work than defining these features and enabling them? I'm not getting any of my overrides to be called. I must be missing something.

    The documentation on OpenXR Features says this:

    "Intercepting OpenXR function calls
    To intercept OpenXR function calls, override OpenXRFeature.HookGetInstanceProcAddr. Returning a different function pointer allows intercepting any OpenXR method. For an example, see the Intercept Feature sample"
     
  18. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    Which overrides are not being called? Also if you have a sample project I can take a look at it, you can private message me a link if you have one.
     
  19. bendikorn

    bendikorn

    Joined:
    Sep 29, 2016
    Posts:
    6
    Hey sorry I was too quick. I am getting the overrides when playing from build! :) but not from editor at the moment.

    [Edit] Was being stupid again. I hadn't enabled the feature under PC, Mac & Linux tab. Was testing in Android build.
     
    Last edited: Nov 18, 2021
    the_real_apoxol likes this.
  20. CBHM

    CBHM

    Joined:
    Feb 12, 2019
    Posts:
    32
  21. RichardRevesz

    RichardRevesz

    Joined:
    Jul 4, 2018
    Posts:
    12
    For me, on the app space change the player is not recentered. I created a feature that should catch OnAppSpaceChange, but it does not work either. I found a workaround as OnSessionBegin works, not reset view, but on editing the guardian. Anyways, wanted to let you know that here might be a bug. MetaXR Feature does not log OnAppSpaceChange as it is supposed to, but logs OnSessionBegin (and others)

    The code that is not working:

    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.Events;
    6. using UnityEngine.XR.OpenXR.Features;
    7.  
    8. #if UNITY_EDITOR
    9. [UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Reset View Feature",
    10.     BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.Android },
    11.     Company = "Unknown",
    12.     Desc = "Feature to catch reset view in headset and apply it in the app.",
    13.     //DocumentationLink = "https://docs.unity.cn/Packages/com.unity.xr.openxr@0.1/manual/index.html",
    14.     OpenxrExtensionStrings = "", // this extension doesn't exist, a log message will be printed that it couldn't be enabled
    15.     Version = "0.0.1",
    16.     FeatureId = featureId)]
    17. #endif
    18.  
    19. public class ResetViewFeature : OpenXRFeature
    20. {
    21.     public const string featureId = "com.unkonwn.resetview";
    22.     public static UnityEvent AppSpaceChanged = new UnityEvent();
    23.     protected override void OnAppSpaceChange(xrSpace)
    24.     {
    25.         base.OnAppSpaceChange(xrSpace);
    26.        }
    27.         AppSpaceChanged.Invoke();
    28.         Debug.Log("AppSpaceChange detected in the feature");
    29.     }
    30. }
    31.  
    The code that is working:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEditor;
    4. using UnityEngine;
    5. using UnityEngine.Events;
    6. using UnityEngine.XR.OpenXR.Features;
    7.  
    8. #if UNITY_EDITOR
    9. [UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Reset View Feature",
    10.     BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.Android },
    11.     Company = "Unknown",
    12.     Desc = "Feature to catch reset view in headset and apply it in the app.",
    13.     //DocumentationLink = "https://docs.unity.cn/Packages/com.unity.xr.openxr@0.1/manual/index.html",
    14.     OpenxrExtensionStrings = "", // this extension doesn't exist, a log message will be printed that it couldn't be enabled
    15.     Version = "0.0.1",
    16.     FeatureId = featureId)]
    17. #endif
    18.  
    19. public class ResetViewFeature : OpenXRFeature
    20. {
    21.     public const string featureId = "com.unkonwn.resetview";
    22.     public static UnityEvent AppSpaceChanged = new UnityEvent();
    23.     protected override void OnSessionBegin(ulong xrSession)
    24.     {
    25.         base.OnSessionBegin(ulong xrSession);
    26.         AppSpaceChanged.Invoke();
    27.         Debug.Log("AppSpaceChange detected in the feature");
    28.     }
    29. }
    30.  
    Unity version 2021.3.24f1, OpenXR plugin 1.7.0
     
    Last edited: Jul 11, 2023