Switching between a VR and Desktop configuration with a ScriptableObject
We wanted to build a single project experience that included first class support for VR and at the same time worked well in a desktop environment.
Builds
We decided on having dedicated builds for desktop and VR. We wanted the ability to turn off VR. To do this we needed a couple of things.
- Some way of configuring the project to be in VR or Desktop mode.
- A way for the project to know what mode it was in and spawn correct player prefab
- Unload VR related loaders.
Configuration
Configuration is handled by a ScriptableObject that looks something like the following:
[CreateAssetMenu]
public class GlobalConfiguration : ScriptableObject
{
[HideInInspector]
public bool useVR;
public void TurnVROn()
{
// ...
}
public void TurnVROff()
{
// ...
}
}
A custom inspector is used to introduce a button that will trigger the TurnVROn and TurnVROff functions.
Configuring VR Loaders
The following chunk of code will assign a loader.
XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Standalone);
XRPackageMetadataStore.AssignLoader(settings.Manager, typeof(Unity.XR.OpenVR.OpenVRLoader).FullName, BuildTargetGroup.Standalone);
Lets break down each of the lines.
-
XRGeneralSettingsPerBuildTarget buildTargetSettings = null;We are creating a variable to store our XRGeneralSettingsPerBuildTarget in.
-
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);Retrieve the build target settings and store them into
buildTargetSettings. -
XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Standalone);Get the XR settings for the Standalone (
BuildTargetGroup.Standalone) build. -
XRPackageMetadataStore.AssignLoader(settings.Manager, typeof(Unity.XR.OpenVR.OpenVRLoader).FullName, BuildTargetGroup.Standalone);Turn the OpenVRLoader on.
If we focus on line 4, we could also do XRPackageMetadataStore.RemoveLoader(...) to remove a loader.
Other types of loaders can be removed / added by changing the loader type from OpenVR to whatever loader is being used.
See also:
Prefab Management
Prefab management is fairly straightforward. Simply have a PlayerSpawner that will look at the globalconfiguration.useVR value and spawn either a VR prefab or a Desktop prefab depending on the scenario. When the prefab is spawned a game event is triggered to let the scene know so it can self-configure from there.