Skip to content

Commit c4b7741

Browse files
committed
Added XR Interaction Toolkit Sample - Built-in Render Pipeline
1 parent 631189d commit c4b7741

File tree

54 files changed

+31016
-0
lines changed

Some content is hidden

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

54 files changed

+31016
-0
lines changed

Packages/webxr-interactions/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88

99
### Added
1010
- Sample Scene - Built-in Render Pipeline.
11+
- XR Interaction Toolkit Sample - Built-in Render Pipeline.
1112

1213
### Changed
1314
- HandMenu to override XR Interaction Toolkit one, as it's needed again.

Packages/webxr-interactions/Samples~/XRInteractionToolkit-BiRP/Editor.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.

Packages/webxr-interactions/Samples~/XRInteractionToolkit-BiRP/Editor/Scripts.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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,234 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Linq;
4+
using Unity.XR.CoreUtils.Editor;
5+
using UnityEditor;
6+
using UnityEditor.PackageManager;
7+
using UnityEditor.PackageManager.Requests;
8+
using UnityEditor.PackageManager.UI;
9+
using UnityEngine;
10+
11+
namespace WebXR.Interactions.Samples.XRInteractionToolkitBiRP.Editor
12+
{
13+
/// <summary>
14+
/// Unity Editor class which registers Project Validation rules for the WebXR + XR Interaction Toolkit sample,
15+
/// checking that other required samples and packages are installed.
16+
/// </summary>
17+
static class WebXRInteractionToolkitSampleProjectValidation
18+
{
19+
const string k_SampleDisplayName = "WebXR + XR Interaction Toolkit sample";
20+
const string k_Category = "WebXR";
21+
const string k_HandsInteractionDemoSampleName = "Hands Interaction Demo";
22+
const string k_ProjectValidationSettingsPath = "Project/XR Plug-in Management/Project Validation";
23+
const string k_HandsPackageName = "com.unity.xr.hands";
24+
const string k_XRIPackageName = "com.unity.xr.interaction.toolkit";
25+
static readonly PackageVersion s_MinimumHandsPackageVersion = new PackageVersion("1.2.1");
26+
static readonly PackageVersion s_RecommendedHandsPackageVersion = new PackageVersion("1.3.0");
27+
static readonly PackageVersion s_MinimumXRIPackageVersion = new PackageVersion("2.5.2");
28+
29+
static readonly BuildTargetGroup[] s_BuildTargetGroups =
30+
((BuildTargetGroup[])Enum.GetValues(typeof(BuildTargetGroup))).Distinct().ToArray();
31+
32+
static readonly List<BuildValidationRule> s_BuildValidationRules = new List<BuildValidationRule>
33+
{
34+
new BuildValidationRule
35+
{
36+
IsRuleEnabled = () => s_HandsPackageAddRequest == null || s_HandsPackageAddRequest.IsCompleted,
37+
Message = $"[{k_SampleDisplayName}] XR Hands ({k_HandsPackageName}) package must be installed or updated to use this sample.",
38+
Category = k_Category,
39+
CheckPredicate = () => PackageVersionUtility.GetPackageVersion(k_HandsPackageName) >= s_MinimumHandsPackageVersion,
40+
FixIt = () =>
41+
{
42+
if (s_HandsPackageAddRequest == null || s_HandsPackageAddRequest.IsCompleted)
43+
InstallOrUpdateHands();
44+
},
45+
FixItAutomatic = true,
46+
Error = true,
47+
},
48+
new BuildValidationRule
49+
{
50+
IsRuleEnabled = () => s_HandsPackageAddRequest == null || s_HandsPackageAddRequest.IsCompleted,
51+
Message = $"[{k_SampleDisplayName}] XR Hands ({k_HandsPackageName}) package must be at version {s_RecommendedHandsPackageVersion} or higher to use the latest sample features.",
52+
Category = k_Category,
53+
CheckPredicate = () => PackageVersionUtility.GetPackageVersion(k_HandsPackageName) >= s_RecommendedHandsPackageVersion,
54+
FixIt = () =>
55+
{
56+
if (s_HandsPackageAddRequest == null || s_HandsPackageAddRequest.IsCompleted)
57+
InstallOrUpdateHands();
58+
},
59+
FixItAutomatic = true,
60+
Error = false,
61+
},
62+
new BuildValidationRule
63+
{
64+
IsRuleEnabled = () => s_XRIPackageAddRequest == null || s_XRIPackageAddRequest.IsCompleted,
65+
Message = $"[{k_SampleDisplayName}] XR Interaction Toolkit ({k_XRIPackageName}) package must be installed or updated to use this sample.",
66+
Category = k_Category,
67+
CheckPredicate = () => PackageVersionUtility.GetPackageVersion(k_XRIPackageName) >= s_MinimumXRIPackageVersion,
68+
FixIt = () =>
69+
{
70+
if (s_XRIPackageAddRequest == null || s_XRIPackageAddRequest.IsCompleted)
71+
InstallOrUpdateXRI();
72+
},
73+
FixItAutomatic = true,
74+
Error = true,
75+
},
76+
new BuildValidationRule
77+
{
78+
Message = $"[{k_SampleDisplayName}] {k_HandsInteractionDemoSampleName} sample from XR Interaction Toolkit ({k_XRIPackageName}) package must be imported or updated to use this sample.",
79+
Category = k_Category,
80+
CheckPredicate = () => TryFindSample(k_XRIPackageName, string.Empty, k_HandsInteractionDemoSampleName, out var sample) && sample.isImported,
81+
FixIt = () =>
82+
{
83+
if (TryFindSample(k_XRIPackageName, string.Empty, k_HandsInteractionDemoSampleName, out var sample))
84+
{
85+
sample.Import(Sample.ImportOptions.OverridePreviousImports);
86+
}
87+
},
88+
FixItAutomatic = true,
89+
Error = true,
90+
},
91+
};
92+
93+
static AddRequest s_HandsPackageAddRequest;
94+
static AddRequest s_XRIPackageAddRequest;
95+
96+
[InitializeOnLoadMethod]
97+
static void RegisterProjectValidationRules()
98+
{
99+
foreach (var buildTargetGroup in s_BuildTargetGroups)
100+
{
101+
BuildValidator.AddRules(buildTargetGroup, s_BuildValidationRules);
102+
}
103+
104+
// Delay evaluating conditions for issues to give time for Package Manager and UPM cache to fully initialize.
105+
EditorApplication.delayCall += ShowWindowIfIssuesExist;
106+
}
107+
108+
static void ShowWindowIfIssuesExist()
109+
{
110+
foreach (var validation in s_BuildValidationRules)
111+
{
112+
if (validation.CheckPredicate == null || !validation.CheckPredicate.Invoke())
113+
{
114+
ShowWindow();
115+
return;
116+
}
117+
}
118+
}
119+
120+
internal static void ShowWindow()
121+
{
122+
// Delay opening the window since sometimes other settings in the player settings provider redirect to the
123+
// project validation window causing serialized objects to be nullified.
124+
EditorApplication.delayCall += () =>
125+
{
126+
SettingsService.OpenProjectSettings(k_ProjectValidationSettingsPath);
127+
};
128+
}
129+
130+
static bool TryFindSample(string packageName, string packageVersion, string sampleDisplayName, out Sample sample)
131+
{
132+
sample = default;
133+
134+
if (!PackageVersionUtility.IsPackageInstalled(packageName))
135+
return false;
136+
137+
IEnumerable<Sample> packageSamples;
138+
try
139+
{
140+
packageSamples = Sample.FindByPackage(packageName, packageVersion);
141+
}
142+
catch (Exception e)
143+
{
144+
Debug.LogError($"Couldn't find samples of the {ToString(packageName, packageVersion)} package; aborting project validation rule. Exception: {e}");
145+
return false;
146+
}
147+
148+
if (packageSamples == null)
149+
{
150+
Debug.LogWarning($"Couldn't find samples of the {ToString(packageName, packageVersion)} package; aborting project validation rule.");
151+
return false;
152+
}
153+
154+
foreach (var packageSample in packageSamples)
155+
{
156+
if (packageSample.displayName == sampleDisplayName)
157+
{
158+
sample = packageSample;
159+
return true;
160+
}
161+
}
162+
163+
Debug.LogWarning($"Couldn't find {sampleDisplayName} sample in the {ToString(packageName, packageVersion)} package; aborting project validation rule.");
164+
return false;
165+
}
166+
167+
static string ToString(string packageName, string packageVersion)
168+
{
169+
return string.IsNullOrEmpty(packageVersion) ? packageName : $"{packageName}@{packageVersion}";
170+
}
171+
172+
static void InstallOrUpdateHands()
173+
{
174+
// Set a 3-second timeout for request to avoid editor lockup
175+
var currentTime = DateTime.Now;
176+
var endTime = currentTime + TimeSpan.FromSeconds(3);
177+
178+
var request = Client.Search(k_HandsPackageName);
179+
if (request.Status == StatusCode.InProgress)
180+
{
181+
Debug.Log($"Searching for ({k_HandsPackageName}) in Unity Package Registry.");
182+
while (request.Status == StatusCode.InProgress && currentTime < endTime)
183+
currentTime = DateTime.Now;
184+
}
185+
186+
var addRequest = k_HandsPackageName;
187+
if (request.Status == StatusCode.Success && request.Result.Length > 0)
188+
{
189+
var versions = request.Result[0].versions;
190+
var verifiedVersion = new PackageVersion(versions.recommended);
191+
var latestCompatible = new PackageVersion(versions.latestCompatible);
192+
if (verifiedVersion < s_RecommendedHandsPackageVersion && s_RecommendedHandsPackageVersion <= latestCompatible)
193+
addRequest = $"{k_HandsPackageName}@{s_RecommendedHandsPackageVersion}";
194+
}
195+
196+
s_HandsPackageAddRequest = Client.Add(addRequest);
197+
if (s_HandsPackageAddRequest.Error != null)
198+
{
199+
Debug.LogError($"Package installation error: {s_HandsPackageAddRequest.Error}: {s_HandsPackageAddRequest.Error.message}");
200+
}
201+
}
202+
203+
static void InstallOrUpdateXRI()
204+
{
205+
// Set a 3-second timeout for request to avoid editor lockup
206+
var currentTime = DateTime.Now;
207+
var endTime = currentTime + TimeSpan.FromSeconds(3);
208+
209+
var request = Client.Search(k_XRIPackageName);
210+
if (request.Status == StatusCode.InProgress)
211+
{
212+
Debug.Log($"Searching for ({k_XRIPackageName}) in Unity Package Registry.");
213+
while (request.Status == StatusCode.InProgress && currentTime < endTime)
214+
currentTime = DateTime.Now;
215+
}
216+
217+
var addRequest = k_XRIPackageName;
218+
if (request.Status == StatusCode.Success && request.Result.Length > 0)
219+
{
220+
var versions = request.Result[0].versions;
221+
var verifiedVersion = new PackageVersion(versions.recommended);
222+
var latestCompatible = new PackageVersion(versions.latestCompatible);
223+
if (verifiedVersion < s_MinimumXRIPackageVersion && s_MinimumXRIPackageVersion <= latestCompatible)
224+
addRequest = $"{k_XRIPackageName}@{s_MinimumXRIPackageVersion}";
225+
}
226+
227+
s_XRIPackageAddRequest = Client.Add(addRequest);
228+
if (s_XRIPackageAddRequest.Error != null)
229+
{
230+
Debug.LogError($"Package installation error: {s_XRIPackageAddRequest.Error}: {s_XRIPackageAddRequest.Error.message}");
231+
}
232+
}
233+
}
234+
}

Packages/webxr-interactions/Samples~/XRInteractionToolkit-BiRP/Editor/Scripts/WebXRInteractionToolkitSampleProjectValidation.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.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "WebXR.Interactions.Samples.XRInteractionToolkitBiRP.Editor",
3+
"rootNamespace": "",
4+
"references": [
5+
"Unity.XR.CoreUtils",
6+
"Unity.XR.CoreUtils.Editor"
7+
],
8+
"includePlatforms": [
9+
"Editor"
10+
],
11+
"excludePlatforms": [],
12+
"allowUnsafeCode": false,
13+
"overrideReferences": false,
14+
"precompiledReferences": [],
15+
"autoReferenced": true,
16+
"defineConstraints": [],
17+
"versionDefines": [],
18+
"noEngineReferences": false
19+
}

Packages/webxr-interactions/Samples~/XRInteractionToolkit-BiRP/Editor/WebXR.Interactions.Samples.XRInteractionToolkitBiRP.Editor.asmdef.meta

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

Packages/webxr-interactions/Samples~/XRInteractionToolkit-BiRP/Materials.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.

0 commit comments

Comments
 (0)