Forum Discussion
viteichris
8 years agoProtege
How do I correctly implement VR focus with Unity (To pass VRC.PC.Input.1)
I'm trying to make sure our app is ready to go, but I'm not certain on what exactly I can/should do to ensure we pass this VRC:
Currently we drop into our pause menu when the app loses focus, but it seems like there's a bit more to be done:
VRC.PC.Input.1
The app must not submit frames or accept input when the user removes the HMD or opens the Universal Menu.And from Unity Lifecycle
VR Focus
[...]When you lose VR focus the user can no longer see your app. You should
stop submitting frames, drop audio, and stop tracking input. You may
also wish to save the game state so you can return the user to where
they left off in your app.
Is there anything that we should be doing application side to handle this (beyond pausing gameplay elements), specifically, how can I tell Unity to stop submitting frames and tracking input?
Alternatively, is there some sort of global Unity state(?) that can be set to handle this (like UnityPlayer.pause/resume) (I'm guessing no : ) ).
Thanks,
7 Replies
Replies have been turned off for this discussion
- viteichrisProtegeasking to ensure a pass / minimise the amount of work I do (or need to re-do :) )
- Raj_OOIHonored Guest@viteichris Did you ever solve this issue? I'm failing this test with the VRCValidator and I cannot find any answers or help, just open questions like yours with no response :(
- viteichrisProtegeI did! Although I can’t remember how. And I’m not at my machine right now to check.
it might have been as simple as setting the timescale to 0 and making sure everything respected that? I’ll check when I’m back in he office on Monday and update this answer! - viteichrisProtegeOK, I'm back in the office and checked. Our pause function is complicated, but essentially it boils down to:- Stop updating everything (timescale 0 or whatever)- DISABLE cameras. (this is the important one)The validator is checking for "app must not submit frames", so if you do `camera.enabled = false` or `camera.gameObject.SetActive(false)` then that camera will stop rendering frames and the validator won't see any!afaict, the validator can't really tell what's happening with input, so you just have to ensure manually that your app isn't doing anything whilst it's in this "pause" state.
- Spoon420ExplorerAdd the following lines to your update method on OVRPlayerControllerif (OVRManager.hasInputFocus){Time.timeScale = 1;CameraRig.enabled = true;}if (OVRManager.hasInputFocus == false){Time.timeScale = 0;CameraRig.enabled = false;}
Oculus should have this as part of their default script there is no reason I know of not too since it is required. - Anoki1972Explorer@Spoon420 How can I use your script but for the camera rig prefab only? I am not using the OVRPlayerController in my game, I am only using the camera rig prefab. Any suggestions?
- Anoki1972ExplorerHere a code that you attach to a game object in your scene and it works for me.using System.Collections;using System.Collections.Generic;using UnityEngine;public class GamePause : MonoBehaviour{public GameObject OVRCameraRig;public GameObject pauseMenuUIThing;public GameObject[] listOfObjectsToHideOnPause;private AudioSource[] audioSources;private void OnEnable(){// try to find camera rig automatically, if it's not set in the Inspector..if (OVRCameraRig == null)OVRCameraRig = GameObject.Find("OVRCameraRig");// this subscribes to Oculus events, so when they fire our functions get called in this scriptOVRManager.HMDUnmounted += PauseGame;OVRManager.HMDMounted += UnPauseGame;OVRManager.VrFocusLost += PauseGame;OVRManager.VrFocusAcquired += UnPauseGame;OVRManager.InputFocusLost += PauseGame;OVRManager.InputFocusAcquired += UnPauseGame;}private void OnDisable(){// this unsubscribes from the Oculus events when they're no longer needed (when this object is disabled etc)OVRManager.HMDUnmounted -= PauseGame;OVRManager.HMDMounted -= UnPauseGame;OVRManager.VrFocusLost -= PauseGame;OVRManager.VrFocusAcquired -= UnPauseGame;OVRManager.InputFocusLost -= PauseGame;OVRManager.InputFocusAcquired -= UnPauseGame;}private void PauseGame(){//Debug.Log("PAUSE! --------------------------------------------");// show menu message thing, if we have one..if (pauseMenuUIThing != null)pauseMenuUIThing.SetActive(true);// if we have objects to hide, let's hide them..for(int i=0; i< listOfObjectsToHideOnPause.Length;i++){listOfObjectsToHideOnPause.SetActive(false);}// find and start all audiosources in the SceneAudioSource[] audioSources = GameObject.FindObjectsOfTypeAll(typeof(AudioSource)) as AudioSource[];for (int i = 0; i < audioSources.Length; i++){audioSources.Pause();}// pause timeTime.timeScale = 0.0f;}private void UnPauseGame(){//Debug.Log("UNPAUSE! --------------------------------------------");if (OVRManager.hasVrFocus && OVRManager.isHmdPresent && OVRManager.hasInputFocus){// hide menu message thing, if we have one..if (pauseMenuUIThing != null)pauseMenuUIThing.SetActive(false);// if we have objects to hide, let's hide them..for (int i = 0; i < listOfObjectsToHideOnPause.Length; i++){listOfObjectsToHideOnPause.SetActive(true);}// find and stop all audioSources in the SceneAudioSource[] audioSources = GameObject.FindObjectsOfTypeAll(typeof(AudioSource)) as AudioSource[];for (int i = 0; i < audioSources.Length; i++){audioSources.UnPause();}// restart timeTime.timeScale = 1.0f;}}}
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device