Skip to content

Commit 7a25656

Browse files
authored
Backport hands subsystem project validation rules from XRI3 branch to main (#991)
* Update MRTKProjectValidation.cs * Update MRTKProjectValidation.cs * Add validation rule for Hand Tracking Subsystem when the MRTK feature is enabled * Update InputValidation.cs * Guard against missing OpenXR package * Update changelogs * Add validation rule to move away from the obsolete provider on Android
1 parent 8bad01d commit 7a25656

File tree

6 files changed

+112
-16
lines changed

6 files changed

+112
-16
lines changed

org.mixedrealitytoolkit.core/Configuration/MRTKProfile.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
using MixedReality.Toolkit.Subsystems;
55
using System.Collections.Generic;
66
using UnityEngine;
7-
using UnityEngine.Audio;
87

98
namespace MixedReality.Toolkit
109
{

org.mixedrealitytoolkit.core/Editor/MRTKProjectValidation.cs

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,7 @@
22
// Licensed under the BSD 3-Clause
33

44
using MixedReality.Toolkit.Editor;
5-
using System;
65
using System.Collections.Generic;
7-
using System.Linq;
86
using Unity.XR.CoreUtils.Editor;
97
using UnityEditor;
108
using UnityEngine;
@@ -16,12 +14,6 @@ namespace MixedReality.Toolkit
1614
/// </summary>
1715
public static class MRTKProjectValidation
1816
{
19-
#pragma warning disable 618
20-
private static readonly BuildTargetGroup[] excludedBuildTargetGroups = new BuildTargetGroup[]
21-
// Need to cast int back to BuildTargetGroup because BuildTargetGroup.WebPlayer is marked as obsolete and treated as an error
22-
{ (BuildTargetGroup)2, BuildTargetGroup.PS3, BuildTargetGroup.XBOX360, BuildTargetGroup.WP8, BuildTargetGroup.BlackBerry, BuildTargetGroup.Tizen, BuildTargetGroup.PSP2,
23-
BuildTargetGroup.PSM, BuildTargetGroup.SamsungTV, BuildTargetGroup.N3DS, BuildTargetGroup.WiiU, BuildTargetGroup.Facebook, BuildTargetGroup.Switch };
24-
#pragma warning restore 618
2517
private const string XRProjectValidationSettingsPath = "Project/XR Plug-in Management/Project Validation";
2618
private const string DefaultMRTKProfileGuid = "c677e5c4eb85b7849a8da406775c299d";
2719
private static readonly Dictionary<BuildTargetGroup, List<BuildValidationRule>> validationRulesDictionary = new Dictionary<BuildTargetGroup, List<BuildValidationRule>>();
@@ -32,7 +24,7 @@ public static class MRTKProjectValidation
3224
/// <remarks>
3325
/// Build targets currently not supported by MRTK will be filtered out.
3426
/// </remarks>
35-
public static readonly BuildTargetGroup[] BuildTargetGroups = ((BuildTargetGroup[])Enum.GetValues(typeof(BuildTargetGroup))).Distinct().Except(excludedBuildTargetGroups).ToArray();
27+
public static readonly BuildTargetGroup[] BuildTargetGroups = { BuildTargetGroup.Standalone, BuildTargetGroup.Android, BuildTargetGroup.WSA };
3628

3729
[MenuItem("Mixed Reality/MRTK3/Utilities/Project Validation", priority = 0)]
3830
private static void MenuItem()
@@ -50,7 +42,7 @@ private static void MRTKProjectValidationCheck()
5042

5143
private static void AddMRTKValidationRules()
5244
{
53-
foreach (var buildTargetGroup in validationRulesDictionary.Keys)
45+
foreach (BuildTargetGroup buildTargetGroup in validationRulesDictionary.Keys)
5446
{
5547
BuildValidator.AddRules(buildTargetGroup, validationRulesDictionary[buildTargetGroup]);
5648
}
@@ -70,7 +62,7 @@ private static void AddMRTKCoreValidationRules()
7062
AddTargetIndependentRules(mrtkCoreTargetIndependentRules);
7163

7264
// Add target-specific rules
73-
foreach (var buildTargetGroup in BuildTargetGroups)
65+
foreach (BuildTargetGroup buildTargetGroup in BuildTargetGroups)
7466
{
7567
// Skip the standalone target as the profile rule for it is already present for all build targets
7668
if (buildTargetGroup != BuildTargetGroup.Standalone)

org.mixedrealitytoolkit.input/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
66

77
### Added
88

9+
* Added a project validation rule to ensure the Unity XR Hands subsystem is enabled in the OpenXR settings when the corresponding MRTK subsystem is enabled. [PR #973](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/973)
910
* Added support for Unity's com.unity.cloud.gltfast and com.unity.cloud.ktx packages when loading controller models. [PR #631](https://github.com/MixedRealityToolkit/MixedRealityToolkit-Unity/pull/631)
1011

1112
### Fixed

org.mixedrealitytoolkit.input/Editor/InputValidation.cs

Lines changed: 97 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,16 @@
99
using UnityEditor.PackageManager;
1010
using UnityEngine;
1111

12+
#if UNITY_OPENXR_PRESENT
13+
using MixedReality.Toolkit.Editor;
14+
using UnityEngine.XR.Hands.OpenXR;
15+
using UnityEngine.XR.OpenXR;
16+
#endif
17+
1218
namespace MixedReality.Toolkit.Input.Editor
1319
{
1420
/// <summary>
15-
/// A class adding input related rule(s) to the validator
21+
/// A class adding input related rule(s) to the validator.
1622
/// </summary>
1723
internal static class InputValidation
1824
{
@@ -22,11 +28,27 @@ private static void AddInputValidationRule()
2228
foreach (var buildTargetGroup in MRTKProjectValidation.BuildTargetGroups)
2329
{
2430
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateSpeechInteractorRule(buildTargetGroup) }, buildTargetGroup);
31+
32+
#if UNITY_OPENXR_PRESENT
33+
// Skip the standalone target as the hand subsystem rule for it is already present for all build targets
34+
if (buildTargetGroup != BuildTargetGroup.Standalone)
35+
{
36+
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateUnityHandsRule(buildTargetGroup) }, buildTargetGroup);
37+
}
38+
#endif
2539
}
26-
MRTKProjectValidation.AddTargetIndependentRules(new List<BuildValidationRule>() { GenerateSkinWeightsRule(), GenerateGLTFastRule() });
40+
MRTKProjectValidation.AddTargetIndependentRules(new List<BuildValidationRule>() { GenerateSkinWeightsRule(), GenerateGLTFastRule(),
41+
#if UNITY_OPENXR_PRESENT
42+
GenerateUnityHandsRule(BuildTargetGroup.Standalone),
43+
#endif
44+
});
2745

2846
// Only generate the KTX rule for platforms related to Meta
29-
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateKTXRule() }, BuildTargetGroup.Android);
47+
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateKTXRule(),
48+
#if UNITY_OPENXR_PRESENT
49+
GenerateAndroidHandsRule(),
50+
#endif
51+
}, BuildTargetGroup.Android);
3052
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateKTXRule() }, BuildTargetGroup.Standalone);
3153
}
3254

@@ -104,5 +126,77 @@ private static BuildValidationRule GenerateKTXRule()
104126
Error = false
105127
};
106128
}
129+
130+
#if UNITY_OPENXR_PRESENT
131+
private static BuildValidationRule GenerateUnityHandsRule(BuildTargetGroup buildTargetGroup)
132+
{
133+
return new BuildValidationRule()
134+
{
135+
IsRuleEnabled = () => MRTKProjectValidation.GetLoadedSubsystemsForBuildTarget(buildTargetGroup)?.Contains(typeof(UnityHandsSubsystem)) ?? false,
136+
Category = "MRTK3",
137+
Message = $"When {nameof(UnityHandsSubsystem)} is enabled for the {buildTargetGroup} build target, " +
138+
$"{nameof(HandTracking)} must also be enabled in the OpenXR settings for {buildTargetGroup}.",
139+
CheckPredicate = () =>
140+
{
141+
OpenXRSettings settings = OpenXRSettings.GetSettingsForBuildTargetGroup(buildTargetGroup);
142+
if (settings == null)
143+
{
144+
return false;
145+
}
146+
147+
HandTracking handFeature = settings.GetFeature<HandTracking>();
148+
return handFeature != null && handFeature.enabled;
149+
},
150+
FixIt = () =>
151+
{
152+
OpenXRSettings settings = OpenXRSettings.GetSettingsForBuildTargetGroup(buildTargetGroup);
153+
if (settings == null)
154+
{
155+
return;
156+
}
157+
158+
HandTracking handFeature = settings.GetFeature<HandTracking>();
159+
if (handFeature != null)
160+
{
161+
handFeature.enabled = true;
162+
EditorUtility.SetDirty(settings);
163+
}
164+
},
165+
FixItMessage = $"Enable {nameof(HandTracking)} in the OpenXR settings.",
166+
Error = true
167+
};
168+
}
169+
170+
private static BuildValidationRule GenerateAndroidHandsRule()
171+
{
172+
// Disable this warning because this rule's purpose is to help migrate away from the obsolete type
173+
#pragma warning disable CS0618 // Type or member is obsolete
174+
return new BuildValidationRule()
175+
{
176+
Category = "MRTK3",
177+
Message = "Hand tracking on Android with the Mixed Reality OpenXR Plugin has been deprecated. " +
178+
$"Please turn off {nameof(OpenXRHandsSubsystem)} in the MRTK profile and use {nameof(UnityHandsSubsystem)} instead.",
179+
CheckPredicate = () => !MRTKProjectValidation.GetLoadedSubsystemsForBuildTarget(BuildTargetGroup.Android)?.Contains(typeof(OpenXRHandsSubsystem)) ?? true,
180+
FixIt = () =>
181+
{
182+
MRTKProfile profile = MRTKSettings.ProfileForBuildTarget(BuildTargetGroup.Android);
183+
if (profile == null)
184+
{
185+
return;
186+
}
187+
188+
profile.LoadedSubsystems.Remove(typeof(OpenXRHandsSubsystem));
189+
if (!profile.LoadedSubsystems.Contains(typeof(UnityHandsSubsystem)))
190+
{
191+
profile.LoadedSubsystems.Add(typeof(UnityHandsSubsystem));
192+
}
193+
EditorUtility.SetDirty(profile);
194+
},
195+
FixItMessage = $"Turn off {nameof(OpenXRHandsSubsystem)} in the MRTK profile and ensure {typeof(UnityHandsSubsystem)} is enabled instead.",
196+
Error = false
197+
};
198+
#pragma warning restore CS0618 // Type or member is obsolete
199+
}
200+
#endif
107201
}
108202
}

org.mixedrealitytoolkit.input/Editor/MRTK.Input.Editor.asmdef

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,11 @@
77
"MixedReality.Toolkit.Input",
88
"Unity.XR.CoreUtils",
99
"Unity.XR.CoreUtils.Editor",
10+
"Unity.XR.Hands",
1011
"Unity.XR.Interaction.Toolkit",
1112
"Unity.XR.Interaction.Toolkit.Editor",
12-
"Unity.XR.Management"
13+
"Unity.XR.Management",
14+
"Unity.XR.OpenXR"
1315
],
1416
"includePlatforms": [
1517
"Editor"
@@ -45,6 +47,11 @@
4547
"name": "com.unity.xr.management",
4648
"expression": "4.2",
4749
"define": "UNITYXR_MANAGEMENT_PRESENT"
50+
},
51+
{
52+
"name": "com.unity.xr.openxr",
53+
"expression": "",
54+
"define": "UNITY_OPENXR_PRESENT"
4855
}
4956
],
5057
"noEngineReferences": false

org.mixedrealitytoolkit.input/Subsystems/Hands/OpenXRHandsSubsystem.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ namespace MixedReality.Toolkit.Input
2828
SubsystemTypeOverride = typeof(OpenXRHandsSubsystem),
2929
ConfigType = typeof(BaseSubsystemConfig))]
3030
#endif // MROPENXR_PRESENT
31+
#if UNITY_ANDROID
32+
[System.Obsolete("Hand tracking on Android with the Mixed Reality OpenXR Plugin has been deprecated. Please use " + nameof(UnityHandsSubsystem) + " instead.")]
33+
#endif
3134
public class OpenXRHandsSubsystem : HandsSubsystem
3235
{
3336
#if MROPENXR_PRESENT && (UNITY_EDITOR_WIN || UNITY_WSA || UNITY_STANDALONE_WIN || UNITY_ANDROID)

0 commit comments

Comments
 (0)