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:
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);
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.
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.
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.
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.
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
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?
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?