Skip to content

Commit 7074e22

Browse files
authored
Merge pull request #9681 from microsoft/feature/uber-profile
Update profiles to support both legacy XR and XR SDK
2 parents 6df4f0a + 65cc9ec commit 7074e22

File tree

93 files changed

+3367
-892
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

93 files changed

+3367
-892
lines changed

Assets/MRTK/Core/Attributes/MixedRealityControllerAttribute.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public class MixedRealityControllerAttribute : Attribute
4444
public SupportedUnityXRPipelines SupportedUnityXRPipelines { get; }
4545

4646
/// <summary>
47-
///
47+
/// Constructor.
4848
/// </summary>
4949
public MixedRealityControllerAttribute(
5050
SupportedControllerType supportedControllerType,

Assets/MRTK/Core/Attributes/MixedRealityExtensionServiceAttribute.cs

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,12 @@ public MixedRealityExtensionServiceAttribute(
102102
RequiresProfile = requiresProfile;
103103
}
104104

105-
#if UNITY_EDITOR
106105
/// <summary>
107106
/// Convenience function for retrieving the attribute given a certain class type.
108107
/// </summary>
109-
/// <remarks>
110-
/// This function is only available in a UnityEditor context.
111-
/// </remarks>
112108
public static MixedRealityExtensionServiceAttribute Find(Type type)
113109
{
114110
return type.GetCustomAttributes(typeof(MixedRealityExtensionServiceAttribute), true).FirstOrDefault() as MixedRealityExtensionServiceAttribute;
115111
}
116-
#endif // UNITY_EDITOR
117112
}
118113
}

Assets/MRTK/Core/Definitions/InputSystem/MixedRealityInputSystemProfile.cs

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -155,13 +155,7 @@ public MixedRealityGesturesProfile GesturesProfile
155155
/// <summary>
156156
/// Returns whether speech is supported for the current language or not
157157
/// </summary>
158-
public bool IsSpeechSupported
159-
{
160-
get
161-
{
162-
return supportedVoiceCultures.Contains(CultureInfo.CurrentUICulture);
163-
}
164-
}
158+
public bool IsSpeechSupported => supportedVoiceCultures.Contains(CultureInfo.CurrentUICulture);
165159

166160
[SerializeField]
167161
[Tooltip("Speech Command profile for wiring up Voice Input to Actions.")]

Assets/MRTK/Core/Definitions/MixedRealityToolkitConfigurationProfile.cs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,25 +157,26 @@ public bool IsBoundarySystemEnabled
157157
}
158158

159159
[SerializeField]
160-
[Tooltip("Boundary System class to instantiate at runtime.")]
160+
[Tooltip("Boundary system class to instantiate at runtime for legacy XR.")]
161161
[Implements(typeof(IMixedRealityBoundarySystem), TypeGrouping.ByNamespaceFlat)]
162-
private SystemType boundarySystemType;
162+
private SystemType boundarySystemType = null;
163+
164+
[SerializeField]
165+
[Tooltip("Boundary system class to instantiate at runtime for XR SDK.")]
166+
[Implements(typeof(IMixedRealityBoundarySystem), TypeGrouping.ByNamespaceFlat)]
167+
private SystemType xrsdkBoundarySystemType = null;
163168

164169
/// <summary>
165-
/// Boundary System class to instantiate at runtime.
170+
/// Boundary system class to instantiate at runtime.
166171
/// </summary>
167-
public SystemType BoundarySystemSystemType
168-
{
169-
get { return boundarySystemType; }
170-
internal set { boundarySystemType = value; }
171-
}
172+
public SystemType BoundarySystemSystemType => (!XRSettingsUtilities.LegacyXRAvailable && xrsdkBoundarySystemType?.Type != null) ? xrsdkBoundarySystemType : boundarySystemType;
172173

173174
[SerializeField]
174175
[Tooltip("Profile for wiring up boundary visualization assets.")]
175176
private MixedRealityBoundaryVisualizationProfile boundaryVisualizationProfile;
176177

177178
/// <summary>
178-
/// Active profile for boundary visualization
179+
/// Active profile for boundary visualization.
179180
/// </summary>
180181
public MixedRealityBoundaryVisualizationProfile BoundaryVisualizationProfile
181182
{

Assets/MRTK/Core/Definitions/Utilities/SupportedPlatforms.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,9 @@ public enum SupportedPlatforms
3030
[Flags]
3131
public enum SupportedUnityXRPipelines
3232
{
33+
#if UNITY_2020_1_OR_NEWER
34+
[Obsolete("The legacy XR pipeline has been removed in Unity 2020 or newer. Please migrate to XR SDK.")]
35+
#endif // UNITY_2020_1_OR_NEWER
3336
LegacyXR = 1 << 0,
3437
XRSDK = 1 << 1,
3538
}

Assets/MRTK/Core/Inspectors/Profiles/DataProviderAccessServiceInspector.cs

Lines changed: 64 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// Copyright (c) Microsoft Corporation.
22
// Licensed under the MIT License.
33

4+
using Microsoft.MixedReality.Toolkit.Utilities;
45
using Microsoft.MixedReality.Toolkit.Utilities.Editor;
56
using System;
67
using System.Collections.Generic;
@@ -10,7 +11,7 @@
1011
namespace Microsoft.MixedReality.Toolkit.Editor
1112
{
1213
/// <summary>
13-
/// Abstract class providing base functionality for data provider management in inspector. Useful for core systems that follow dataprovider access model.
14+
/// Abstract class providing base functionality for data provider management in inspector. Useful for core systems that follow data provider access model.
1415
/// Designed to target ScriptableObject profile classes that configure services who support data providers.
1516
/// These profile ScriptableObject classes should contain an array of IMixedRealityServiceConfigurations that configure a list of data providers for this service configuration
1617
/// </summary>
@@ -28,8 +29,9 @@ protected class ServiceConfigurationProperties
2829
}
2930

3031
/// <summary>
31-
/// Returns SerializedProperty object that wraps references to array of <see cref="IMixedRealityServiceConfiguration"/> stored on the inspected target object
32+
/// Allows implementations of a IMixedRealityDataProviderAccess system's inspector to provide custom data provider representations for data providers.
3233
/// </summary>
34+
/// <returns>SerializedProperty object that wraps references to array of <see cref="IMixedRealityServiceConfiguration"/> stored on the inspected target object.</returns>
3335
protected abstract SerializedProperty GetDataProviderConfigurationList();
3436

3537
/// <summary>
@@ -46,6 +48,13 @@ protected class ServiceConfigurationProperties
4648
private SerializedProperty providerConfigurations;
4749
private List<bool> providerFoldouts = new List<bool>();
4850

51+
#if UNITY_2019
52+
private static readonly GUIContent GeneralProvidersLabel = new GUIContent("General Providers");
53+
#endif // UNITY_2019
54+
55+
private readonly XRPipelineUtility xrPipelineUtility = new XRPipelineUtility();
56+
private readonly List<SystemType> delayedDisplayProviders = new List<SystemType>();
57+
4958
private static readonly GUIContent ComponentTypeLabel = new GUIContent("Type");
5059
private static readonly GUIContent SupportedPlatformsLabel = new GUIContent("Supported Platform(s)");
5160

@@ -56,6 +65,10 @@ protected override void OnEnable()
5665
{
5766
base.OnEnable();
5867

68+
#if UNITY_2019
69+
xrPipelineUtility.Enable();
70+
#endif // UNITY_2019
71+
5972
providerConfigurations = GetDataProviderConfigurationList();
6073

6174
if (providerFoldouts == null || providerFoldouts.Count != providerConfigurations.arraySize)
@@ -80,7 +93,7 @@ protected virtual void AddDataProvider()
8093

8194
serializedObject.ApplyModifiedProperties();
8295

83-
var providerType = GetDataProviderConfiguration(providerConfigurations.arraySize - 1).ComponentType;
96+
SystemType providerType = GetDataProviderConfiguration(providerConfigurations.arraySize - 1).ComponentType;
8497
providerType.Type = null;
8598

8699
providerFoldouts.Add(false);
@@ -99,15 +112,15 @@ protected virtual void RemoveDataProvider(int index)
99112
}
100113

101114
/// <summary>
102-
/// Applies the given concrete dataprovider type properties to the provided <see cref="IMixedRealityServiceConfiguration"/> instance (as represented by <see cref="ServiceConfigurationProperties"/>).
115+
/// Applies the given concrete data provider type properties to the provided <see cref="IMixedRealityServiceConfiguration"/> instance (as represented by <see cref="ServiceConfigurationProperties"/>).
103116
/// Requires <see cref="MixedRealityDataProviderAttribute"/> on concrete type class to pull initial values
104117
/// that will be applied to the <see cref="ServiceConfigurationProperties"/> container SerializedProperties
105118
/// </summary>
106119
protected virtual void ApplyProviderConfiguration(Type dataProviderType, ServiceConfigurationProperties providerProperties)
107120
{
108121
if (dataProviderType != null)
109122
{
110-
if (MixedRealityDataProviderAttribute.Find(dataProviderType) is MixedRealityDataProviderAttribute providerAttribute)
123+
if (MixedRealityExtensionServiceAttribute.Find(dataProviderType) is MixedRealityDataProviderAttribute providerAttribute)
111124
{
112125
providerProperties.componentName.stringValue = !string.IsNullOrWhiteSpace(providerAttribute.Name) ? providerAttribute.Name : dataProviderType.Name;
113126
providerProperties.providerProfile.objectReferenceValue = providerAttribute.DefaultProfile;
@@ -143,9 +156,53 @@ protected bool RenderDataProviderList(GUIContent addContentLabel, GUIContent rem
143156
return true;
144157
}
145158

159+
#if UNITY_2019
160+
xrPipelineUtility.RenderXRPipelineTabs();
161+
#endif // UNITY_2019
162+
163+
delayedDisplayProviders.Clear();
164+
146165
for (int i = 0; i < providerConfigurations.arraySize; i++)
147166
{
148-
changed |= RenderDataProviderEntry(i, removeContentLabel, dataProviderProfileType);
167+
SystemType serviceType = GetDataProviderConfiguration(i).ComponentType;
168+
169+
if (serviceType.Type != null && MixedRealityExtensionServiceAttribute.Find(serviceType.Type) is MixedRealityDataProviderAttribute providerAttribute)
170+
{
171+
// Using == here to compare flags because we want to know if this is the only supported pipeline
172+
// Providers that support multiple pipelines are rendered below the tabbed section
173+
if (providerAttribute.SupportedUnityXRPipelines == xrPipelineUtility.SelectedPipeline)
174+
{
175+
changed |= RenderDataProviderEntry(i, removeContentLabel, serviceType, dataProviderProfileType);
176+
delayedDisplayProviders.Add(null);
177+
}
178+
else if (providerAttribute.SupportedUnityXRPipelines == (SupportedUnityXRPipelines)(-1))
179+
{
180+
delayedDisplayProviders.Add(serviceType);
181+
}
182+
else
183+
{
184+
// Add null to ensure the delayedDisplayProviders list has an identical size to providerConfigurations.arraySize
185+
// This is so we can iterate through without keeping track of i separately
186+
delayedDisplayProviders.Add(null);
187+
}
188+
}
189+
else
190+
{
191+
delayedDisplayProviders.Add(serviceType);
192+
}
193+
}
194+
195+
#if UNITY_2019
196+
EditorGUILayout.LabelField(GeneralProvidersLabel, EditorStyles.boldLabel);
197+
#endif // UNITY_2019
198+
199+
for (int i = 0; i < delayedDisplayProviders.Count; i++)
200+
{
201+
SystemType service = delayedDisplayProviders[i];
202+
if (service != null)
203+
{
204+
changed |= RenderDataProviderEntry(i, removeContentLabel, service, dataProviderProfileType);
205+
}
149206
}
150207

151208
return changed;
@@ -156,14 +213,12 @@ protected bool RenderDataProviderList(GUIContent addContentLabel, GUIContent rem
156213
/// Renders properties of <see cref="IMixedRealityServiceConfiguration"/> instance at provided index in inspector.
157214
/// Also renders inspector view of data provider's profile object and its contents if applicable and foldout is expanded.
158215
/// </summary>
159-
protected bool RenderDataProviderEntry(int index, GUIContent removeContent, System.Type dataProviderProfileType = null)
216+
private bool RenderDataProviderEntry(int index, GUIContent removeContent, SystemType serviceType, Type dataProviderProfileType = null)
160217
{
161218
bool changed = false;
162219
SerializedProperty provider = providerConfigurations.GetArrayElementAtIndex(index);
163220
ServiceConfigurationProperties providerProperties = GetDataProviderConfigurationProperties(provider);
164221

165-
var serviceType = GetDataProviderConfiguration(index).ComponentType;
166-
167222
// Don't hide new data providers added via the UI, otherwise there's no easy way to change their type
168223
if (serviceType?.Type == null && !MixedRealityProjectPreferences.ShowNullDataProviders && !providerProperties.componentName.stringValue.StartsWith(NewDataProvider))
169224
{

Assets/MRTK/Core/Inspectors/Profiles/MixedRealityControllerVisualizationProfileInspector.cs

Lines changed: 45 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,11 @@ public class MixedRealityControllerVisualizationProfileInspector : BaseMixedReal
3535
private static bool showControllerDefinitions = true;
3636
private SerializedProperty controllerVisualizationSettings;
3737

38+
private readonly XRPipelineUtility xrPipelineUtility = new XRPipelineUtility();
39+
3840
private MixedRealityControllerVisualizationProfile thisProfile;
3941

4042
private float defaultLabelWidth;
41-
private float defaultFieldWidth;
4243

4344
private const string ProfileTitle = "Controller Visualization Settings";
4445
private const string ProfileDescription = "Define all the custom controller visualizations you'd like to use for each controller type when they're rendered in the scene.\n\n" +
@@ -49,7 +50,10 @@ protected override void OnEnable()
4950
base.OnEnable();
5051

5152
defaultLabelWidth = EditorGUIUtility.labelWidth;
52-
defaultFieldWidth = EditorGUIUtility.fieldWidth;
53+
54+
#if UNITY_2019
55+
xrPipelineUtility.Enable();
56+
#endif // UNITY_2019
5357

5458
thisProfile = target as MixedRealityControllerVisualizationProfile;
5559

@@ -173,32 +177,50 @@ private void RenderControllerList(SerializedProperty controllerList)
173177
return;
174178
}
175179

180+
#if UNITY_2019
181+
xrPipelineUtility.RenderXRPipelineTabs();
182+
#endif // UNITY_2019
183+
176184
for (int i = 0; i < controllerList.arraySize; i++)
177185
{
178-
EditorGUILayout.Space();
179-
EditorGUILayout.BeginHorizontal();
180-
181186
var controllerSetting = controllerList.GetArrayElementAtIndex(i);
182187
var mixedRealityControllerMappingDescription = controllerSetting.FindPropertyRelative("description");
183-
bool hasValidType = thisProfile.ControllerVisualizationSettings[i].ControllerType != null &&
184-
thisProfile.ControllerVisualizationSettings[i].ControllerType.Type != null;
188+
SystemType controllerType = thisProfile.ControllerVisualizationSettings[i].ControllerType;
189+
bool hasValidType = controllerType != null &&
190+
controllerType.Type != null;
191+
192+
if (hasValidType)
193+
{
194+
MixedRealityControllerAttribute controllerAttribute = MixedRealityControllerAttribute.Find(controllerType.Type);
195+
if (controllerAttribute != null && !controllerAttribute.SupportedUnityXRPipelines.HasFlag(xrPipelineUtility.SelectedPipeline))
196+
{
197+
continue;
198+
}
199+
}
200+
else if (!MixedRealityProjectPreferences.ShowNullDataProviders)
201+
{
202+
continue;
203+
}
204+
205+
EditorGUILayout.Space();
185206

186207
mixedRealityControllerMappingDescription.stringValue = hasValidType
187-
? thisProfile.ControllerVisualizationSettings[i].ControllerType.Type.Name.ToProperCase()
208+
? controllerType.Type.Name.ToProperCase()
188209
: "Undefined Controller";
189210

190211
serializedObject.ApplyModifiedProperties();
191-
var mixedRealityControllerHandedness = controllerSetting.FindPropertyRelative("handedness");
192-
EditorGUILayout.LabelField($"{mixedRealityControllerMappingDescription.stringValue} {((Handedness)mixedRealityControllerHandedness.intValue).ToString().ToProperCase()} Hand", EditorStyles.boldLabel);
212+
SerializedProperty mixedRealityControllerHandedness = controllerSetting.FindPropertyRelative("handedness");
193213

194-
if (GUILayout.Button(ControllerMinusButtonContent, EditorStyles.miniButtonRight, GUILayout.Width(24f)))
214+
using (new EditorGUILayout.HorizontalScope())
195215
{
196-
controllerList.DeleteArrayElementAtIndex(i);
197-
EditorGUILayout.EndHorizontal();
198-
return;
199-
}
216+
EditorGUILayout.LabelField($"{mixedRealityControllerMappingDescription.stringValue} {((Handedness)mixedRealityControllerHandedness.intValue).ToString().ToProperCase()} Hand", EditorStyles.boldLabel);
200217

201-
EditorGUILayout.EndHorizontal();
218+
if (GUILayout.Button(ControllerMinusButtonContent, EditorStyles.miniButtonRight, GUILayout.Width(24f)))
219+
{
220+
controllerList.DeleteArrayElementAtIndex(i);
221+
return;
222+
}
223+
}
202224

203225
EditorGUILayout.PropertyField(controllerSetting.FindPropertyRelative("controllerType"));
204226
EditorGUILayout.PropertyField(controllerSetting.FindPropertyRelative("controllerVisualizationType"));
@@ -207,11 +229,14 @@ private void RenderControllerList(SerializedProperty controllerList)
207229
{
208230
EditorGUILayout.HelpBox("A controller type must be defined!", MessageType.Error);
209231
}
210-
211-
bool isOculusType = thisProfile.ControllerVisualizationSettings[i].ControllerType.Type.FullName.Contains("OculusXRSDKTouchController");
212-
if (isOculusType)
232+
else
213233
{
214-
EditorGUILayout.HelpBox("Oculus Touch controller model visualization is not managed by MRTK, refer to the Oculus XRSDK Device Manager to configure controller visualization settings", MessageType.Error);
234+
// Only check for Oculus if we already know the type is valid (otherwise, null ref)
235+
bool isOculusType = controllerType.Type.FullName.Contains("OculusXRSDKTouchController");
236+
if (isOculusType)
237+
{
238+
EditorGUILayout.HelpBox("Oculus Touch controller model visualization is not managed by MRTK, refer to the Oculus XRSDK Device Manager to configure controller visualization settings", MessageType.Error);
239+
}
215240
}
216241

217242
var handednessValue = mixedRealityControllerHandedness.intValue - 1;

Assets/MRTK/Core/Inspectors/Profiles/MixedRealityInputSystemProfileInspector.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -211,14 +211,11 @@ protected override ServiceConfigurationProperties GetDataProviderConfigurationPr
211211
/// <inheritdoc/>
212212
protected override IMixedRealityServiceConfiguration GetDataProviderConfiguration(int index)
213213
{
214-
MixedRealityInputSystemProfile targetProfile = target as MixedRealityInputSystemProfile;
215-
if (targetProfile != null)
214+
MixedRealityInputSystemProfile profile = target as MixedRealityInputSystemProfile;
215+
var configurations = (profile != null) ? profile.DataProviderConfigurations : null;
216+
if (configurations != null && index >= 0 && index < configurations.Length)
216217
{
217-
var configurations = targetProfile.DataProviderConfigurations;
218-
if (configurations != null && index >= 0 && index < configurations.Length)
219-
{
220-
return configurations[index];
221-
}
218+
return configurations[index];
222219
}
223220

224221
return null;

0 commit comments

Comments
 (0)