Skip to content

Commit 90f7fb8

Browse files
committed
Add MRTKFocusFeature
1 parent 813124d commit 90f7fb8

File tree

5 files changed

+194
-5
lines changed

5 files changed

+194
-5
lines changed

UnityProjects/MRTKDevTemplate/Assets/XR/Settings/OpenXR Package Settings.asset

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -363,6 +363,26 @@ MonoBehaviour:
363363
company: Unity
364364
priority: 0
365365
required: 0
366+
--- !u!114 &-5000202051992085229
367+
MonoBehaviour:
368+
m_ObjectHideFlags: 0
369+
m_CorrespondingSourceObject: {fileID: 0}
370+
m_PrefabInstance: {fileID: 0}
371+
m_PrefabAsset: {fileID: 0}
372+
m_GameObject: {fileID: 0}
373+
m_Enabled: 1
374+
m_EditorHideFlags: 0
375+
m_Script: {fileID: 11500000, guid: 30587bb28b5390644ae70f801841a073, type: 3}
376+
m_Name: MRTKFocusFeature Android
377+
m_EditorClassIdentifier:
378+
m_enabled: 1
379+
nameUi: MRTK3 Session Focus
380+
version: 4.0.0
381+
featureIdInternal: org.mixedreality.toolkit.input.focus
382+
openxrExtensionStrings:
383+
company: Mixed Reality Toolkit Contributors
384+
priority: 0
385+
required: 0
366386
--- !u!114 &-4989097037534641705
367387
MonoBehaviour:
368388
m_ObjectHideFlags: 0
@@ -394,6 +414,7 @@ MonoBehaviour:
394414
- {fileID: -5492763381520605560}
395415
- {fileID: 720212866400260749}
396416
- {fileID: -2783824018031006640}
417+
- {fileID: -4614918767838866102}
397418
- {fileID: 4334429337943452973}
398419
- {fileID: -5448262054166454653}
399420
- {fileID: -9173909432611776730}
@@ -429,6 +450,26 @@ MonoBehaviour:
429450
company: Unity
430451
priority: 0
431452
required: 0
453+
--- !u!114 &-4614918767838866102
454+
MonoBehaviour:
455+
m_ObjectHideFlags: 0
456+
m_CorrespondingSourceObject: {fileID: 0}
457+
m_PrefabInstance: {fileID: 0}
458+
m_PrefabAsset: {fileID: 0}
459+
m_GameObject: {fileID: 0}
460+
m_Enabled: 1
461+
m_EditorHideFlags: 0
462+
m_Script: {fileID: 11500000, guid: 30587bb28b5390644ae70f801841a073, type: 3}
463+
m_Name: MRTKFocusFeature Standalone
464+
m_EditorClassIdentifier:
465+
m_enabled: 1
466+
nameUi: MRTK3 Session Focus
467+
version: 4.0.0
468+
featureIdInternal: org.mixedreality.toolkit.input.focus
469+
openxrExtensionStrings:
470+
company: Mixed Reality Toolkit Contributors
471+
priority: 0
472+
required: 0
432473
--- !u!114 &-3765664599707111037
433474
MonoBehaviour:
434475
m_ObjectHideFlags: 0
@@ -536,6 +577,7 @@ MonoBehaviour:
536577
- {fileID: -7229825001273466666}
537578
- {fileID: 4508051287823359615}
538579
- {fileID: 2835676197965704550}
580+
- {fileID: -5000202051992085229}
539581
- {fileID: -7431403579802858517}
540582
- {fileID: -3273436338079595365}
541583
- {fileID: 8773911662759437579}
@@ -651,6 +693,26 @@ MonoBehaviour:
651693
company: Unity
652694
priority: 0
653695
required: 0
696+
--- !u!114 &-1685409458817180080
697+
MonoBehaviour:
698+
m_ObjectHideFlags: 0
699+
m_CorrespondingSourceObject: {fileID: 0}
700+
m_PrefabInstance: {fileID: 0}
701+
m_PrefabAsset: {fileID: 0}
702+
m_GameObject: {fileID: 0}
703+
m_Enabled: 1
704+
m_EditorHideFlags: 0
705+
m_Script: {fileID: 11500000, guid: 30587bb28b5390644ae70f801841a073, type: 3}
706+
m_Name: MRTKFocusFeature Metro
707+
m_EditorClassIdentifier:
708+
m_enabled: 1
709+
nameUi: MRTK3 Session Focus
710+
version: 4.0.0
711+
featureIdInternal: org.mixedreality.toolkit.input.focus
712+
openxrExtensionStrings:
713+
company: Mixed Reality Toolkit Contributors
714+
priority: 0
715+
required: 0
654716
--- !u!114 &-1310172892294911860
655717
MonoBehaviour:
656718
m_ObjectHideFlags: 0
@@ -934,6 +996,7 @@ MonoBehaviour:
934996
- {fileID: 8785654261743502636}
935997
- {fileID: 2622006578924267534}
936998
- {fileID: -6733472631637007722}
999+
- {fileID: -1685409458817180080}
9371000
- {fileID: 4575689165844638740}
9381001
- {fileID: 6698335440458243644}
9391002
- {fileID: -2219742231848666541}

org.mixedrealitytoolkit.input/Editor/InputValidation.cs

Lines changed: 53 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,40 @@ private static void AddInputValidationRule()
2727
{
2828
foreach (var buildTargetGroup in MRTKProjectValidation.BuildTargetGroups)
2929
{
30-
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateSpeechInteractorRule(buildTargetGroup) }, buildTargetGroup);
30+
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() {
31+
GenerateSpeechInteractorRule(buildTargetGroup)
32+
}, buildTargetGroup);
3133

3234
#if UNITY_OPENXR_PRESENT
3335
// Skip the standalone target as the hand subsystem rule for it is already present for all build targets
3436
if (buildTargetGroup != BuildTargetGroup.Standalone)
3537
{
36-
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateUnityHandsRule(buildTargetGroup) }, buildTargetGroup);
38+
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() {
39+
GenerateUnityHandsRule(buildTargetGroup),
40+
GenerateMRTKFocusFeatureRule(buildTargetGroup)
41+
}, buildTargetGroup);
3742
}
3843
#endif
3944
}
40-
MRTKProjectValidation.AddTargetIndependentRules(new List<BuildValidationRule>() { GenerateSkinWeightsRule(), GenerateGLTFastRule(),
45+
MRTKProjectValidation.AddTargetIndependentRules(new List<BuildValidationRule>() {
46+
GenerateSkinWeightsRule(),
47+
GenerateGLTFastRule(),
4148
#if UNITY_OPENXR_PRESENT
4249
GenerateUnityHandsRule(BuildTargetGroup.Standalone),
4350
#endif
4451
});
4552

4653
// Only generate the KTX rule for platforms related to Meta
47-
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateKTXRule(),
54+
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() {
55+
GenerateKTXRule(),
4856
#if UNITY_OPENXR_PRESENT
4957
GenerateAndroidHandsRule(),
5058
#endif
5159
}, BuildTargetGroup.Android);
52-
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() { GenerateKTXRule() }, BuildTargetGroup.Standalone);
60+
61+
MRTKProjectValidation.AddTargetDependentRules(new List<BuildValidationRule>() {
62+
GenerateKTXRule()
63+
}, BuildTargetGroup.Standalone);
5364
}
5465

5566
private static BuildValidationRule GenerateSpeechInteractorRule(BuildTargetGroup buildTargetGroup)
@@ -197,6 +208,43 @@ private static BuildValidationRule GenerateAndroidHandsRule()
197208
};
198209
#pragma warning restore CS0618 // Type or member is obsolete
199210
}
211+
212+
private static BuildValidationRule GenerateMRTKFocusFeatureRule(BuildTargetGroup buildTargetGroup)
213+
{
214+
return new BuildValidationRule()
215+
{
216+
Category = "MRTK3",
217+
Message = $"For MRTK3 input to work correctly on OpenXR, enable {MRTKFocusFeature.FriendlyName} in the OpenXR Settings.",
218+
CheckPredicate = () =>
219+
{
220+
OpenXRSettings settings = OpenXRSettings.GetSettingsForBuildTargetGroup(buildTargetGroup);
221+
if (settings == null)
222+
{
223+
return false;
224+
}
225+
226+
MRTKFocusFeature focusFeature = settings.GetFeature<MRTKFocusFeature>();
227+
return focusFeature != null && focusFeature.enabled;
228+
},
229+
FixIt = () =>
230+
{
231+
OpenXRSettings settings = OpenXRSettings.GetSettingsForBuildTargetGroup(buildTargetGroup);
232+
if (settings == null)
233+
{
234+
return;
235+
}
236+
237+
MRTKFocusFeature focusFeature = settings.GetFeature<MRTKFocusFeature>();
238+
if (focusFeature != null)
239+
{
240+
focusFeature.enabled = true;
241+
EditorUtility.SetDirty(settings);
242+
}
243+
},
244+
FixItMessage = $"Enable {nameof(MRTKFocusFeature)} in the OpenXR settings.",
245+
Error = true
246+
};
247+
}
200248
#endif
201249
}
202250
}

org.mixedrealitytoolkit.input/Features.meta

Lines changed: 8 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) Mixed Reality Toolkit Contributors
2+
// Licensed under the BSD 3-Clause
3+
4+
using Unity.XR.CoreUtils.Bindings.Variables;
5+
using UnityEngine;
6+
using UnityEngine.XR.OpenXR.Features;
7+
8+
#if UNITY_EDITOR
9+
using UnityEditor;
10+
using UnityEditor.XR.OpenXR.Features;
11+
#endif
12+
13+
namespace MixedReality.Toolkit.Input
14+
{
15+
/// <summary>
16+
/// Provides focus data based on XrSession state.
17+
/// </summary>
18+
#if UNITY_EDITOR
19+
[OpenXRFeature(
20+
UiName = FriendlyName,
21+
Desc = "Provides focus data based on XrSession state.",
22+
Company = "Mixed Reality Toolkit Contributors",
23+
Version = "4.0.0",
24+
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android },
25+
Category = FeatureCategory.Feature,
26+
FeatureId = "org.mixedreality.toolkit.input.focus")]
27+
#endif
28+
public sealed class MRTKFocusFeature : OpenXRFeature
29+
{
30+
/// <summary>
31+
/// The "friendly" name for this feature.
32+
/// </summary>
33+
public const string FriendlyName = "MRTK3 Session Focus";
34+
35+
/// <summary>
36+
/// Whether the current XrSession has focus or not, stored as a bindable variable that can be subscribed to for value changes.
37+
/// </summary>
38+
/// <remarks>Always <see langword="true"/> in the editor.</remarks>
39+
public static IReadOnlyBindableVariable<bool> XrSessionFocused => xrSessionFocused;
40+
private static readonly BindableVariable<bool> xrSessionFocused = new(Application.isEditor);
41+
42+
/// <inheritdoc/>
43+
protected override void OnSessionStateChange(int oldState, int newState)
44+
{
45+
// If we've lost focus...
46+
// XR_SESSION_STATE_FOCUSED = 5
47+
if (oldState == 5)
48+
{
49+
xrSessionFocused.Value = false;
50+
}
51+
// ...or if we've gained focus
52+
// XR_SESSION_STATE_FOCUSED = 5
53+
else if (newState == 5)
54+
{
55+
xrSessionFocused.Value = true;
56+
}
57+
}
58+
}
59+
}

org.mixedrealitytoolkit.input/Features/MRTKFocusFeature.cs.meta

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)