[OpenXR] Interaction Profiles not present when building in batch mode

,

Unity: 2021.1.16f1
XR Plugin Management: 4.0.7
OpenXR Plugin: 1.2.8
Hardware: Oculus Quest Link, HP Reverb 2 and HTC Vive.

I’m encountering a strange problem, where controller devices are not recognized in builds created by our CI pipeline. It works fine in Editor and even when creating a build from the Editor GUI. Trying to narrow down where this bug came from, I skimmed through the CI job logs and found the following:

ProgressiveSceneManager::Cancel()
building x86_64 windows player!
At least one interaction profile must be added.  Please select which controllers you will be testing against in the Features menu.
UnityEngine.StackTraceUtility:ExtractStackTrace ()
UnityEngine.DebugLogHandler:LogFormat (UnityEngine.LogType,UnityEngine.Object,string,object[])
UnityEngine.Logger:Log (UnityEngine.LogType,object)
UnityEngine.Debug:LogWarning (object)
UnityEditor.XR.OpenXR.OpenXRProjectValidation:LogBuildValidationIssues (UnityEditor.BuildTargetGroup) (at Library/PackageCache/com.unity.xr.openxr@1.2.8/Runtime/OpenXRProjectValidation.cs:209)
UnityEditor.XR.OpenXR.OpenXRProjectValidationBuildStep:OnPreprocessBuild (UnityEditor.Build.Reporting.BuildReport) (at Library/PackageCache/com.unity.xr.openxr@1.2.8/Editor/OpenXRProjectValidationWindow.cs:295)
UnityEditor.Build.BuildPipelineInterfaces/<>c__DisplayClass15_0:<OnBuildPreProcess>b__1 (UnityEditor.Build.IPreprocessBuildWithReport)
UnityEditor.Build.BuildPipelineInterfaces:InvokeCallbackInterfacesPair<UnityEditor.Build.IPreprocessBuild, UnityEditor.Build.IPreprocessBuildWithReport> (System.Collections.Generic.List`1<UnityEditor.Build.IPreprocessBuild>,System.Action`1<UnityEditor.Build.IPreprocessBuild>,System.Collections.Generic.List`1<UnityEditor.Build.IPreprocessBuildWithReport>,System.Action`1<UnityEditor.Build.IPreprocessBuildWithReport>,bool)
UnityEditor.Build.BuildPipelineInterfaces:OnBuildPreProcess (UnityEditor.Build.Reporting.BuildReport)

(Filename: Library/PackageCache/com.unity.xr.openxr@1.2.8/Runtime/OpenXRProjectValidation.cs Line: 209)

In the editor window it looks like this:
7502438--924397--upload_2021-9-17_13-25-21.png

I presume that there is something wrong with the deserialization of the openxr asset when using batch mode. This is causing no interaction profiles to be active in the build and therefore my controller devices do not show up.

This is the call we use to create the build in batch mode:

C:\MyProject\Unity\2021.1.16f1\Editor\Unity.exe
-rebuildlibrary
-projectPath
C:\Gitlab-Runner\builds\MyProject
-buildWindows64Player
C:\Gitlab-Runner\builds\MyProject\Build\MyProject.exe
-batchmode
-quit
-logFile
C:\Gitlab-Runner\builds\MyProject\logFile.txt

Edit: I could also reproduce this locally when building from the CLI
Edit2: Also happens without ```-rebuildlibrary

Found a respective bug report

1 Like

That bug report shows the behavior wasn’t present in 4.0.5 and is present in 4.0.6. I think this is where the issue was introduced:


Looks like it was technically a bug, but desired behavior, that BeginPackageInitialization wasn’t executing when using batch mode.

As a workaround, you might be able to use OnPreprocessBuild to re-enable the desired interaction profiles before the build starts?

Yes, it looks like this is where the problem was introduced.

I already tried do a workaround in the PreprocessBuild step. However the interaction profiles in OpenXRSettings are all read-only and I couldn’t figure out how to activate them manually.

Edit: Going back to 4.0.5 seems to be the best workaround so far.

I haven’t tested this with the batchmode bug, but this is able to repopulate the Interaction Profiles list of the OpenXR settings if it’s been emptied.

using UnityEditor;
using UnityEngine.XR.OpenXR;
using System.Linq;
using UnityEngine.XR.OpenXR.Features;
public class ModifyOpenXRSettings : EditorWindow
{
    private static readonly string[] enabledFeatures = new []{"HTCViveControllerProfile", "MicrosoftMotionControllerProfile", "OculusTouchControllerProfile", "ValveIndexControllerProfile"};

    [MenuItem("Tools/Test Modification")]
    private static void EnableOpenXRInteractionFeatures() {
        var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Standalone);
        var features = settings.GetFeatures<OpenXRInteractionFeature>();

        foreach (var feature in features) {
            var settingName = feature.GetType().Name;

            feature.enabled = enabledFeatures.Contains(settingName);
        }

        EditorUtility.SetDirty(settings);
    }
}
1 Like

I just tried this but unfortunately it didn’t work.

public class FixOpenXRInteractionProfiles : IPreprocessBuildWithReport
{
    private static readonly string[] enabledFeatures =
    {
        "HTCViveControllerProfile",
        "MicrosoftMotionControllerProfile",
        "OculusTouchControllerProfile",
        "ValveIndexControllerProfile"
    };

    public int callbackOrder => -1;
  
    public void OnPreprocessBuild(BuildReport report)
    {
        var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(BuildTargetGroup.Standalone);
      
        if (settings == null)
        {
            Debug.Log($"No OpenXR settings found.");
            return;
        }

        var features = settings.GetFeatures<OpenXRInteractionFeature>();

        if (settings.featureCount == 0)
        {
            Debug.Log($"No interaction profiles defined. Working around Unity bugs once again ...");

            foreach (var feature in features) {
                var settingName = feature.GetType().Name;
                feature.enabled = enabledFeatures.Contains(settingName);
            }
            EditorUtility.SetDirty(settings);
          
        }
        else
        {
            Debug.Log($"{features.Length} Interaction profiles found. No action required. " +
                      $"Features: {string.Join(", ", features.Where(f => f.enabled).Select(f => f.name))}");
        }
    }
}

Output was:

No interaction profiles defined. Working around Unity bugs once again ...
At least one interaction profile must be added.  Please select which controllers you will be testing against in the Features menu.

Edit: I also tried to call XRPackageInitializationBootstrap.BeginPackageInitialization() by reflection but that does not work either.

Oooph. This is quite vexing. Thanks for trying it.

We have a fix for this issue in XR.SDK.MANAGEMENT that is making its way through the testing / release cycle. The Issue is that BeginPackageInitialization is called too early, before the asset database is loaded and is wiping out the openxr package settings. We dont have an ETA yet for release of this fix.

Our testing has showed this only happens when the Library folder is missing though. So there may be a workaround that you could try while you wait for the fix if you are blocked, but note that I have not personally tried this. This assumes that your Library folder is missing and that is why you are running into this issue.

  1. Make a copy of the OpenXR Package settings file
  2. Run unity in batch mode with some empty executeMethod function (this will build the library folder but also clobber your package settings)
  3. Copy the old package settings over the newly clobbered one after unity exits
  4. Run your actual batchmode operation
2 Likes

Thank you for clearing this up. For now, I will stick to 4.0.5 to avoid this bug.

1 Like