Editor Programmatically Set the VR System in XR Plugin Management

Hello,

Before the XR Plugin Management functionality was introduced, we used an editor script (for a build server, etc) that would enable Oculus VR support using:

PlayerSettings.virtualRealitySupported = true;
UnityEditorInternal.VR.VREditor.SetVREnabledDevicesOnTargetGroup(BuildTargetGroup.Android, new string[] { "Oculus" });

I’m unclear how to accomplish the same now in XR Plugin Management. I’ve seen mentions on the forum of XRPackageMetadataStore.AssignLoader. Is this intended to give us the same functionality?

I’m reading the docs, but I’m confused about the reference to the XRManagerSettings instance. Is this a ScriptableObject that only needs to be created if you want to programmatically add a plugin in the editor? The docs for it are vaguely worded:

Any help much appreciated!

XRPackageMetadataStore.AssignLoader

Yes, this is intended as a way to do the same thing.

The XRManagerSettings instance should be created for you as a ScriptableObject. It is required by XR Management as it is what contains the actual list of loaders and manages their lifetimes and state transitions. You shouldn’t need to do anything other than get the settings instance you need for the build target you want.

Here is an example specific to Oculus as above:

string loaderTypeName = "Unity.XR.Oculus.OculusLoader";
var androidXRSettings = XRGeneralSettings.Instance.SettingsForBuildTarget(BuildTargetGroup.Android);
if (androidXRSettings == null)
{
androidSettings = ScriptableObject.CreateInstance<XRGeneralSettings>() as XRGeneralSettings;
XRGeneralSettings.Instance.SetSettingsForBuildTarget(BuildTargetGroup.Android, androidSettings);
}
XRPackageMetadataStore.AssignLoader(andriodXRSettings, loaderTypeName, BuildTargetGroup.Android);
3 Likes

Hello,

Thank you very much for the response!

I’m also thrilled there’s an API for this. Thanks!

I’m having trouble understanding the difference between XRGeneralSettings and XRGeneralSettingsPerBuildTarget. One is in UnityEngine, and the other in UnityEditor.

First, your example has:

var androidXRSettings = XRGeneralSettings.Instance.SettingsForBuildTarget(BuildTargetGroup.Android);

However, XRGeneralSettings doesn’t have a SettingsForBuildTarget method. That does exist, though, in XRGeneralSettingsPerBuildTarget as a static method. My confusion: the method to set it back is not static, it requires an instance. Looking at both the docs and code, I don’t see or understand the relationship between XRGeneralSettings and XRGeneralSettingsPerBuildTarget.

Finally, the last line of your example:

XRPackageMetadataStore.AssignLoader(androidXRSettings, loaderTypeName, BuildTargetGroup.Android);

But that method takes as the first parameter an XRManagerSettings. How is this created?

I really appreciate the help and would love just a bit of clarification.

Thanks!

Sorry, my bad for typing code directly in without checking it.

For 1 you are correct. You can useXRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget. XRGeneralSettingsPerBuildTarget is a ScriptableObject container that holds XRGeneralSettings ScriptableObject instances for each specific build target configured. XRGeneralSettings contains global settings information and configuration data configured in the editor and to be used at runtime.

For the second, use XRGeneralSettings.Manager to get the instance of XRManagerSettings you need. So in this case you’d pass in androidSettings.Manager. If the Manager instance is null, you can create it in the same way as the XRGeneralSettings instance:

var assignedSettings = ScriptableObject.CreateInstance<XRManagerSettings>() as XRManagerSettings;
androidSettings.AssignedSettings = assignedSettings;
EditorUtility.SetDirty(androidSettings); // Make sure this gets picked up for serialization later.

Hello,

Ok, understood. I’m still unclear on how to set it back, though. So I can get it using the static method on XRGeneralSettingsPerBuildTarget:

string loaderTypeName = "Unity.XR.Oculus.OculusLoader";
var androidXRSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.Android);
if (androidXRSettings == null)
{
  androidXRSettings = ScriptableObject.CreateInstance<XRGeneralSettings>();
  //TODO -> I need an instance of XRGeneralSettingsPerBuildTarget to call SetSettingsForBuildTarget here?
}

But setting it requires an instance of XRGeneralSettingsPerBuildTarget, there is no static set.

Thanks!

For your TODO:

XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
2 Likes

Thank you for your time and patience!

Thank you for yours given the issues with the code I originally provided. Good luck!

I miss having the list you could just reorder in editor, I don’t understand why it is gone.

1 Like

@ROBYER1_1 For planning purposes for future changes to management I was hoping you wouldn’t mind answering a a question?

What use cases would be (re-)enabled for you by re-introducing that functionality?

Thanks

Mainly rapid testing in Editor, on a machine that has OpenVR/SteamVR on it, WMR and Oculus, I wanted to test with whichever headset I have plugged in at the time, it was quicker to reorder the list. As now if I want to test WMR, I have to untick both Oculus and OpenVR as they try to run before it.

Similarly, if I want to use Mock HMD loader for quick editor play mode testing of code without a headset plugged in, have to untick WMR, OpenVR and Oculus before I can use Mock HMD.

I also really pushed with QA to get Mock HMD back as it was important for that scripting/testing of code without a headset workflow I sometimes use.

It also felt reliable for builds on windows, if I had the list in a certain order I could be sure the build would try to run with a certain plugin first like WMR rather than trying to run OpenVR/SteamVR which will run first otherwise.

Thank you.

1 Like

I am hoping that the upcoming OpenXR plugin is a stable and suitable ‘all in one’ plugin that runs on Oculus, WMR and SteamVR/OpenVR at least. I would be very keen for news on that, my complaints about plugin ordering here may become redundant when that comes out

Can someone tell me, how to enable/disable certain XRLoaders via editor script?

            XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
            EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
            XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Android);           
            Debug.Log("BuildTargetGroup.Android -> automaticLoading:" + settings.InitManagerOnStart);
            //HOW to toggle loaders here?

You can use the XRPackageMetadataStore.AssignLoader and XRPackageMetadataStore.RemoveLoader APIs to do that.

I am allready trying: XRPackageMetadataStore.RemoveLoader(settings.Manager, "Oculus Loader", BuildTargetGroup.Android) but it does not alter the checkbox, e.g. the method returns false. I tried also “Oculus” as name for the loader, but this does not work, too. Do you have a tip? :slight_smile:

If you close the settings window and reopen it (i.e. causing the window to reload/redraw) does the checkbox change?

I get it now working with “GetType().FullName” from the given loader, for oculus the name would be “Unity.XR.Oculus.OculusLoader”. However, there are no changes of the checkboxes. Closing/Opening the window did not helped. Maybe it is also a logic thing, so calling XRPackageMetadataStore.RemoveLoader, XRPackageMetadataStore.AssignLoader should act like clicking on the checkbox?

Why is there no simple “enable” flag for the xrloader, I think that would make life a bit easier?

And you are passing in the XRManagerSettings instance from XRGeneralSettings.Manager?

XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Android);         
XRPackageMetadataStore.RemoveLoader(settings.Manager, "Unity.XR.Oculus.OculusLoader", BuildTargetGroup.Android);
1 Like