Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Editor Programmatically Set the VR System in XR Plugin Management

Discussion in 'AR/VR (XR) Discussion' started by FromTheFuture, Sep 18, 2020.

  1. FromTheFuture

    FromTheFuture

    Joined:
    Jul 25, 2012
    Posts:
    41
    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:
    Code (CSharp):
    1. PlayerSettings.virtualRealitySupported = true;
    2. 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!
     
  2. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    > 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);
    ```
     
    ROBYER1 and FromTheFuture like this.
  3. FromTheFuture

    FromTheFuture

    Joined:
    Jul 25, 2012
    Posts:
    41
    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:
    Code (CSharp):
    1. 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:
    Code (CSharp):
    1.  
    2. 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!
     
  4. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    Sorry, my bad for typing code directly in without checking it.

    For 1 you are correct. You can use`XRGeneralSettingsPerBuildTarget.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:

    Code (CSharp):
    1. var assignedSettings = ScriptableObject.CreateInstance<XRManagerSettings>() as XRManagerSettings;
    2. androidSettings.AssignedSettings = assignedSettings;
    3. EditorUtility.SetDirty(androidSettings); // Make sure this gets picked up for serialization later.            
     
  5. FromTheFuture

    FromTheFuture

    Joined:
    Jul 25, 2012
    Posts:
    41
    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:
    Code (CSharp):
    1. string loaderTypeName = "Unity.XR.Oculus.OculusLoader";
    2. var androidXRSettings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.Android);
    3. if (androidXRSettings == null)
    4. {
    5.   androidXRSettings = ScriptableObject.CreateInstance<XRGeneralSettings>();
    6.   //TODO -> I need an instance of XRGeneralSettingsPerBuildTarget to call SetSettingsForBuildTarget here?
    7. }
    But setting it requires an instance of XRGeneralSettingsPerBuildTarget, there is no static set.

    Thanks!
     
  6. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    For your TODO:

    Code (CSharp):
    1.  
    2. XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
    3. EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
    4.  
     
    jmcgraw961 and FromTheFuture like this.
  7. FromTheFuture

    FromTheFuture

    Joined:
    Jul 25, 2012
    Posts:
    41
    Thank you for your time and patience!
     
  8. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    Thank you for yours given the issues with the code I originally provided. Good luck!
     
  9. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,420
    I miss having the list you could just reorder in editor, I don't understand why it is gone.
     
  10. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    @ROBYER1 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
     
  11. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,420
    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.
     
  12. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    Thank you.
     
    ROBYER1 likes this.
  13. ROBYER1

    ROBYER1

    Joined:
    Oct 9, 2015
    Posts:
    1,420
    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
     
  14. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    Can someone tell me, how to enable/disable certain XRLoaders via editor script?

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

    Attached Files:

  15. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
  16. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    I am allready trying:
    Code (CSharp):
    1. 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? :)
     
  17. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    If you close the settings window and reopen it (i.e. causing the window to reload/redraw) does the checkbox change?
     
  18. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    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?
     
  19. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    Why is there no simple "enable" flag for the xrloader, I think that would make life a bit easier?
     
  20. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    And you are passing in the XRManagerSettings instance from XRGeneralSettings.Manager?

    Code (CSharp):
    1. XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
    2. EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
    3. XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Android);        
    4. XRPackageMetadataStore.RemoveLoader(settings.Manager, "Unity.XR.Oculus.OculusLoader", BuildTargetGroup.Android);
    5.  
     
    masta-yoda likes this.
  21. joejo

    joejo

    Unity Technologies

    Joined:
    May 26, 2016
    Posts:
    958
    You're not enabling the loader, you are adding it to the fall through list of potential loaders that will run on the target. It's a bit more complicated in that there is quite bit of work involved in "enabling" a loader for a target.
     
    masta-yoda likes this.
  22. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    Works now as expected, thank you! :) Have a nice weekend!
     
    masta-yoda likes this.
  23. masta-yoda

    masta-yoda

    Joined:
    Apr 19, 2020
    Posts:
    81
    Zapan15, could you please share the final approach to switch on/off certain XR Loaders from a script? I'm trying to implement a CI build and need certain plugins to be disabled in certain configurations.
     
  24. masta-yoda

    masta-yoda

    Joined:
    Apr 19, 2020
    Posts:
    81
    Actually, the script above worked, I've just added a strongly typed declaration:

    Code (CSharp):
    1.  
    2. XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
    3. EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
    4. XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Android);      
    5. XRPackageMetadataStore.RemoveLoader(settings.Manager, typeof(Unity.XR.Oculus.OculusLoader).FullName, BuildTargetGroup.Android);
    6.  
     
  25. masta-yoda

    masta-yoda

    Joined:
    Apr 19, 2020
    Posts:
    81
    That's too bad, I have switched off the loaders, but the DLL are still being copied to the output folder messing with the Oculus validation:

    upload_2020-11-27_23-0-3.png


    Code (CSharp):
    1. ERROR: The package contains DLL libraries that are known to cause issues when running on the Oculus platform. These files must be removed prior to uploading:
    2.     C:\Sources\battle-arena-vr\CIBuild\BattleArenaVR-OculusRift-2.3.241.241\Battle Arena VR_Data\Managed\Unity.XR.OpenVR.dll
    3.     C:\Sources\battle-arena-vr\CIBuild\BattleArenaVR-OculusRift-2.3.241.241\Battle Arena VR_Data\Plugins\x86_64\steam_api64.dll
    Any solution for that? Except of manually deleting files after the build is completed, I'm already doing that, I would like to build a package without this DLL being included initially.
     
  26. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    I assume that you are somewhere referencing some load scripts or the like?
    I do not fully understand what you want with the dlls, e.g. which dlls should be included in your build?
     
  27. masta-yoda

    masta-yoda

    Joined:
    Apr 19, 2020
    Posts:
    81
    Unity.XR.OpenVR.dll should be excluded for my build otherwise when I upload the package to Oculus, it rejects it. Is I switch off the OpenVR loader, the dll is still in the output folder.
     
  28. Zapan15

    Zapan15

    Joined:
    Apr 11, 2011
    Posts:
    168
    We have not checked this, and will probably have the same issue. We'll check and come back here once we found a solution for this.
     
    masta-yoda likes this.
  29. Simon_Nordon

    Simon_Nordon

    Joined:
    Nov 30, 2018
    Posts:
    22
    I was able to enable and disable loaders and settings via script for Unity XR Plugin Management. I specifically wanted the ability to quickly switch build settings between Oculus Quest and Android Tablet.

    here is the code for enabling:

    Code (CSharp):
    1.  if(buildDevice == BuildDevice.OCULUSQUEST)
    2.             {
    3.                 androidSettings.InitManagerOnStart = true;
    4.                 XRPackageMetadataStore.AssignLoader(androidSettings.AssignedSettings, typeof(Unity.XR.Oculus.OculusLoader).FullName, BuildTargetGroup.Android);
    5.                 EditorUtility.SetDirty(androidSettings);
    6. }
    Where androidSettings is referencing the scriptable object of the same name in my XR Settings.

    Otherwise, If I'm building to the android tablet it is as follows;

    Code (CSharp):
    1. else if(buildDevice == BuildDevice.ANDROIDTABLET)
    2.             {
    3.                 androidSettings.InitManagerOnStart = false;
    4.                 androidSettings.AssignedSettings.loaders.Clear();
    5. }
     
    salvolannister likes this.
  30. HAIRGROW

    HAIRGROW

    Joined:
    May 17, 2013
    Posts:
    17
    @masta-yoda Have you found a solution for removing the OpenVR.dll when creating an Oculus build. I'm the process of creating an application for both and was wondering how I can ensure that none of the OpenVR dlls are not included in the Oculus builds.

    What lead me to this thread is that I'm trying to create a build script that will allow me to switch between OpenVR and Oculus using the new XR Plugin Management. I'm new to this whole process and have read through the documentation, but I'm not clear on how to set it up to handle both scenarios. So I'm curious if anyone can provide and example for both.
     
  31. nomadic

    nomadic

    Joined:
    Mar 4, 2010
    Posts:
    41
    This is working for most loaders, but adding and removing don't work for OpenXRLoader (UnityEngine.XR.OpenXR.OpenXRLoader)
     
    chrisMary likes this.
  32. jamie_xr

    jamie_xr

    Joined:
    Feb 28, 2020
    Posts:
    50
    I'm running into some troubles here. Here's the situation, I have a tool that can switch between different plugins, by disabling the ones I don't want using
    `XRPackageMetadataStore.RemoveLoader` and then adding the ones I do using `
    XRPackageMetadataStore.AssignLoader`.

    Specifically, in my situation I'm switching between Oculus and OpenXR.

    When trying to modify the OpenXRLoader using these functions, it only works if the window is not open when I click the button to run my tool.
    Oculus can be toggled off and on, ok, but OpenXR will not enable OR disable.

    Now this isn't a huge deal, however when I run it through my CI, this is all invoked via command line. It also does not work. (I guess the window isn't technically open when I run via command line).

    Additionally those functions to assign and remove loaders always return true for me.

    Unity 2020.3.6f1
    OpenXR plugin 1.2.2
     
  33. Tallek

    Tallek

    Joined:
    Apr 21, 2014
    Posts:
    32
    I am also having trouble with disabling the OpenXR plugin while the settings window is open. Seems to work whenever the window is closed though. Anybody found a solution for this yet?
     
  34. jamie_xr

    jamie_xr

    Joined:
    Feb 28, 2020
    Posts:
    50
    It's a been a while, so i'm gonna bump this.
    Also tagging @the_real_apoxol. Is this known?
     
  35. the_real_apoxol

    the_real_apoxol

    Unity Technologies

    Joined:
    Dec 18, 2020
    Posts:
    467
    Can you please submit a bug report with a small sample project so we can get this tracked and look into it faster? Let me know what issue # you get if you do. Thanks.
     
  36. Brady

    Brady

    Joined:
    Sep 25, 2008
    Posts:
    2,447
    I'm having the same problems. I can manually remove (or have a script automatically delete after build) the unwanted DLLs. But I also have other XR loaders that are loading at runtime on Windows even though they are only for Android and only show up in the Android list of XR loaders. It causes runtime errors. No actual interruption in the app, fortunately, but runtime errors nevertheless. This is on 2019.4.26f1.
     
  37. salvolannister

    salvolannister

    Joined:
    Jan 3, 2019
    Posts:
    50
    This script worked for me, but sometimes when I change things in editor it stops working and when I build for Quest I have the application opening in 2D. Does this happen also to you?

    I can't understand why this happens, but to solve the problem I delete the XR settings, then in edit>Project Setting I remove the oculus support and I add it again
     
  38. jmcgraw961

    jmcgraw961

    Joined:
    Jun 7, 2021
    Posts:
    9
    I've noticed a theater effect happens when no plugin-providers have been selected. I wonder if the script disabled settings but failed to enable it again?
     
  39. lrb

    lrb

    Joined:
    Jun 21, 2014
    Posts:
    26
    Still the same here on Unity 2021.3 LTS, it works for everything else except OpenXR, if the window is visible (which was an excelent workaround, so at least when we're not looking at it, it works! Thanks).
     
    unitypsycurio likes this.
  40. ashtorak

    ashtorak

    Joined:
    Feb 19, 2014
    Posts:
    53
    I have the following issue: I am starting with my target platform set to Linux. I want to switch to Windows, enable the OpenXR Plugin, and build it. It seems enabling the plugin works fine with using the code below. But then the build fails saying that only Windows targets are supported. So it doesn't switch the target before building it seems. How would I do this?

    Code (CSharp):
    1. XRGeneralSettingsPerBuildTarget buildTargetSettings = null;
    2. EditorBuildSettings.TryGetConfigObject(XRGeneralSettings.k_SettingsKey, out buildTargetSettings);
    3. XRGeneralSettings settings = buildTargetSettings.SettingsForBuildTarget(BuildTargetGroup.Standalone);    
    4. XRPackageMetadataStore.AssignLoader(settings.Manager, "Unity.XR.OpenXR.OpenXRLoader", BuildTargetGroup.Standalone);
    5.  
    6. BuildPipeline.BuildPlayer(buildPlayerOptions);
     
  41. chilton

    chilton

    Joined:
    May 6, 2008
    Posts:
    512
    Despite efforts to be more socially acceptable, I still cuss regularly.

    I just read this thread and realized how many times I was up against bugs in this pipeline and didn't realize it. How many months, possibly years, of development time were lost to this. I think the best path forward for me, is to just duplicate my effort across multiple projects. At least then I don't lose time hunting invisible demons in the build process.

    I'm at a loss for new cuss words, the old ones just don't do. Oh, maybe I should learn some cuss words for another language. That would be somehow fitting here.

    -Chilton The Increasingly Profane
     
  42. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    381
    The check that outputs that error message does the following:

    Code (CSharp):
    1. (BuildPipeline.GetBuildTargetGroup(EditorUserBuildSettings.activeBuildTarget) != BuildTargetGroup.Standalone) || (EditorUserBuildSettings.activeBuildTarget == BuildTarget.StandaloneWindows64)
    And clicking "fix it" does:

    EditorUserBuildSettings.SwitchActiveBuildTarget(BuildTargetGroup.Standalone, BuildTarget.StandaloneWindows64)


    Try that?
     
    ashtorak likes this.
  43. ashtorak

    ashtorak

    Joined:
    Feb 19, 2014
    Posts:
    53
    This line was what I was looking for, thx! :)
    Somehow I couldn't find it in the docs. Interesting approach to look up what the "fix it" is calling. You are searching for the message in the source code or how does it work?
     
  44. thep3000

    thep3000

    Unity Technologies

    Joined:
    Aug 9, 2013
    Posts:
    381
    Yeah, c# package source code is readable. Search for the error message within the openxr package and you'll find it.
     
    ashtorak likes this.