Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Bug Unity XR -- "Single player apps must pause when the user removes the HMD or opens the Oculus Dash."

Discussion in 'VR' started by BrainSlugs83, Apr 16, 2021.

  1. BrainSlugs83

    BrainSlugs83

    Joined:
    Jun 18, 2015
    Posts:
    38
    I'm using the new Unity XR framework with Oculus XR, and my Quest game failed the App Lab review because it doesn't pause when the user opens the system menu.

    I feel like this used to "just work" -- but now it doesn't anymore -- is this a bug that the Unity team plans to fix, or do I have to do something in code now to make it all work properly again?

    I'm not really sure how to proceed since this seems like a bit of an engine tier thing (yeah I know I can pause time myself, but that can have side effects, and I feel like this used to be automatic -- I'm also not aware of any way to detect if the menu is open using the Unity XR APIs -- if you are, please share).
     
  2. amaestas

    amaestas

    Unity Technologies

    Joined:
    Feb 5, 2020
    Posts:
    18
  3. BrainSlugs83

    BrainSlugs83

    Joined:
    Jun 18, 2015
    Posts:
    38
    Hey! Thank you so much for following up -- that looks like the secret sauce I was missing! -- I will take a look at that tonight and let you know if it solves my issue (I have a feeling it will)! :)

    Though I do have concerns with this:
    1. For one, the compliance rule states that we should only pause if loses focus to the Oculus Dash (specifically) -- obviously doing a carte blanche approach, and pausing for everything isn't penalized by compliance -- but it seems like wrong behavior -- like, there are other apps like fitness trackers and stuff (and more coming in the future) -- and according to the page you linked, the whole point of focus awareness is to not pause the app when those items are being displayed and interacted with (i.e. "Focus awareness allows [the] UI [...] to appear as an overlay on top of an app without pausing the immersive experience").
      • So, is there a way to tell what the focus was lost to? -- Or what's the best practice here to make sure we're not pausing our app inappropriately, every time the focus is lost?
    2. My second concern is more of of a feedback item -- regarding this being intentional -- and the implications that has on Unity usability for XR development. -- My concern is that it means the default behavior for Oculus apps is to not be compliant -- and I feel like compliance should be the default behavior (i.e. you should have to opt-out of compliance if you want to do something weird, not opt-in to if you want to do something normal :confused:). -- Honestly, one of the reason's I'm using a game engine, (such as Unity), is so that I don't have to deal with hairy platform implementation issues.
      [To be clear -- this is feedback; not meant to be an attack of any kind; it just seems like the wrong behavior to me.]
    And again, thank you so much for pointing me at this!! -- (I probably wouldn't have found this information on my own!) :D
     
    Last edited: Jun 10, 2022
  4. R1PFake

    R1PFake

    Joined:
    Aug 7, 2015
    Posts:
    533
    Did your app get accepted to AppLab?
    What was your final solution, is it enough to handle OnApplicationFocus and set the time scale to 0 for the "pause" or did you have to change other things for a "true pause"?
     
    BrainSlugs83 likes this.
  5. ChristopherKroll

    ChristopherKroll

    Joined:
    Feb 12, 2015
    Posts:
    7
    Just wanted to share this "gotcha." The OnApplicationFocus call happens inconsistently when running your Quest app through the Unity Editor + Link. However, it works correctly when fully built and run independently on a headset.
     
    elpko, azevedco and BrainSlugs83 like this.
  6. BrainSlugs83

    BrainSlugs83

    Joined:
    Jun 18, 2015
    Posts:
    38
    Apologies for the late reply, I had some annoying medical issues that made VR pretty inaccessible to me for the last year; so I kind of fell off the planet for awhile.
    Yes, it did -- like another month later -- and I only did the bare minimum, setting the time scale to zero for any and all OnAppFocus events. -- as I never got any further guidance there. -- I think I had to change the code in one of my components to respect that setting, but otherwise I was okay.
    Yeah, again... it definitely works fine when you are only running it vanilla on a headset, but the documentation specifies that other apps can raise this event, and that it shouldn't always be responded to by pausing (so it's probably not limited to the Unity Editor).

    I think for 90% of the users and use cases it's fine -- but the whole point of compliance is to catch those 10% of usability issues... -- So that's why I'm asking if there's a way to get metadata about the event that's raised. (i.e. who raised it? is it actually a blocking menu? or is just an overlay added by another app? etc.)
     
    Last edited: Jun 10, 2022
    Ymmersive likes this.
  7. VeryBadPenny

    VeryBadPenny

    Joined:
    Jun 3, 2018
    Posts:
    40
    Just want to add a few comments here - I went down the same path but for the benefit of anyone following, here is a code snippet from my working app; I'm using ApplicationFocus and ApplicationPause (possibly overkill? not sure if this gets invoked on Quest) and also setting timeScale=0 as mentioned above. You will also need to hold any IEnumerators you have which are frame-based, i.e.
    yield return null;
    type of stuff, because the frames still loop when paused. I catch this in my IEnumerator with something like
    while (GameManager.Instance.Paused) { yield return null; }
    ... obviously you may not have a GameManager singleton like me.

    Code (CSharp):
    1.  
    2.     private bool _paused;
    3.  
    4.     [ContextMenu("Pause ON")]  private void PauseON() => Pause(true);
    5.     [ContextMenu("Pause OFF")] private void PauseOFF() => Pause(false);
    6.  
    7.     public void OnApplicationPause(bool pauseStatus)
    8.     {
    9.         // https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnApplicationPause.html
    10.         Debug.Log($"OnApplicationPause received {pauseStatus}");
    11.         Pause(pauseStatus);
    12.     }
    13.  
    14.     void OnApplicationFocus(bool hasFocus)
    15.     {
    16.         // https://docs.unity3d.com/ScriptReference/MonoBehaviour.OnApplicationFocus.html
    17.         Debug.Log($"OnApplicationFocus received {hasFocus}");
    18.    
    19.         // honestly do not want this to require Game window has focus in editor
    20.         #if !UNITY_EDITOR
    21.         Pause(!hasFocus);
    22.         #endif
    23.     }
    24.  
    25.     public void Pause(bool pauseStatus)
    26.     {
    27.         if (pauseStatus == true)
    28.         {
    29.             Time.timeScale = 0;
    30.             AudioListener.pause = true;
    31.             AudioManager.Instance.SubtitlesClear();
    32.         }
    33.         else
    34.         {
    35.             Time.timeScale = 1;
    36.             AudioListener.pause = false;
    37.         }
    38.         _paused = pauseStatus;
    39.         Debug.Log($"Pause: {pauseStatus}");
    40.     }
    41.  
    P.S. This is not a bug and the thread should probably be renamed by the OP.