上传YomovSDK

This commit is contained in:
Sora丶kong
2026-03-03 03:15:46 +08:00
parent 9096da7e6c
commit eb97f31065
6477 changed files with 1932208 additions and 3 deletions

View File

@@ -0,0 +1,5 @@
{
"timestamp": 1744827431,
"signature": "i4oVbM3Hou2VRxS/swQg429pOx0Z0ezK+EosVuSw7q449q6nELSh8SJU/yF3ypEQqY3lwOb8rEtGSfOHN9zZ2rJua6kUNt+Qc4y+qwZcpIiB73r2cmWjvPZbvJwI6NKRYhV0Q/brOXiFZvZ+yX00jCilxyHA4SqQtsRYcDPRgJwJq9FqIUcrIDZom9AkDeXcyEMP38cKYVyXQn8WJjNZ4QIyCX8bYPQjWis0duQbQDJX3NaHmHsV0+c3VstVzaOu/s9kQYOMTBtRqx9/zDOBtaBEW349zOHPoOjHH9xeOhPJP1D6heANqKZR98AIMM+97pEvyp7yx2W6CIaXWF8s8VXD7Nc2smYhLDBFvhy3kxHfV/7tE2G1sV/wJO+upEladc0oOK5tnBFh8y+EFQINGrT6rCDhYaWf27PBOnFi+jQlDQK3g+ITWm/t/OTtnzRNhpM1vmxC7SjOZhb0hoBjfyC+WD/hf8tzwOnvnJ89wfQdEqbF/ikl/SH6h2G3JW4A",
"publicKey": "LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlJQm9qQU5CZ2txaGtpRzl3MEJBUUVGQUFPQ0FZOEFNSUlCaWdLQ0FZRUFzdUhXYUhsZ0I1cVF4ZEJjTlJKSAordHR4SmoxcVY1NTdvMlZaRE1XaXhYRVBkRTBEMVFkT1JIRXNSS1RscmplUXlERU83ZlNQS0ZwZ1A3MU5TTnJCCkFHM2NFSU45aHNQVDhOVmllZmdWem5QTkVMenFkVmdEbFhpb2VpUnV6OERKWFgvblpmU1JWKytwbk9ySTRibG4KS0twelJlNW14OTc1SjhxZ1FvRktKT0NNRlpHdkJMR2MxSzZZaEIzOHJFODZCZzgzbUovWjBEYkVmQjBxZm13cgo2ZDVFUXFsd0E5Y3JZT1YyV1VpWXprSnBLNmJZNzRZNmM1TmpBcEFKeGNiaTFOaDlRVEhUcU44N0ZtMDF0R1ZwCjVNd1pXSWZuYVRUemEvTGZLelR5U0pka0tldEZMVGdkYXpMYlpzUEE2aHBSK0FJRTJhc0tLTi84UUk1N3UzU2cKL2xyMnZKS1IvU2l5eEN1Q20vQWJkYnJMbXk0WjlSdm1jMGdpclA4T0lLQWxBRWZ2TzV5Z2hSKy8vd1RpTFlzUQp1SllDM0V2UE16ZGdKUzdGR2FscnFLZzlPTCsxVzROY05yNWdveVdSUUJ0cktKaWlTZEJVWmVxb0RvSUY5NHpCCndGbzJJT1JFdXFqcU51M3diMWZIM3p1dGdtalFra3IxVjJhd3hmcExLWlROQWdNQkFBRT0KLS0tLS1FTkQgUFVCTElDIEtFWS0tLS0tCg"
}

View File

@@ -0,0 +1,500 @@
# Changelog
All notable changes to this package will be documented in this file.
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
<!--
> **Notes**
> When updating the Changelog, please ensure we follow the standards for ordering headers as outlined here: [US-0039](https://standards.ds.unity3d.com/Standards/US-0039/). Specifically: Under ## headers, ### \<type\> headers are listed in this order: Added, Changed, Deprecated, Removed, Fixed, Security
-->
## [1.14.3] - 2025-04-20
### Fixed
* Fixed Multiview Render Regions feature regression.
## [1.14.2] - 2025-03-20
### Added
* Added a validation rule about the minimum Android API level is 24.
* Added support for visible triangle mesh to be available for use in post processing.
### Changed
* Modified the Meta Quest Support feature to use the updated Khronos OpenXR loader library.
* Changed OpenXR loader version to 1.1.45.
### Fixed
* Fixed an issue that enabled interaction profiles setting not being saved after reopened the project.
* Fixed a bug that depth submission mode corrupting the spacewarp depth texture.
* Fixed a bug that wrong view configuration type being selected as primary view and causing rendering issues.
* Fixed an issue on Android platforms where `xrCreateSwapchainAndroidSurfaceKHR` was attempted to be used even when the XR Composition Layers package wasn't installed.
* Fixed an issue that Meta XR simulator can't launch properly on Mac.
## [1.14.1] - 2025-02-14
### Added
* Added a validation rule to the Meta Quest Support feature to ensure that your app's default interface orientation uses a supported value.
### Fixed
* Fixed the OpenXRFeatureBuildHooks class so it now grabs the OpenXRSettings object from the given build target during build processing.
* Fixed duplicate OpenXR feature assets being added to the OpenXRSettings asset when upgrading to a newer OpenXR package.
* Fixed rendering problems with Mixed Reality Capture.
* Fixed a debug log spamming issue regarding ignored event types. This message could be logged multiple times per frame and was not helpful.
* Fixed Meta-specific eye-tracking manifest permissions to be added only to apps targeting Meta Quest Pro devices.
* Fixed an issue where spacewarp may assign motion vector textures to wrong render passes when using secondary views.
* Fixed a bug when allocating array swapchain failed, the index was incremented incorrectly.
* Fixed an issue when OpenXR feature didn't have all the attribute entries setup.
## [1.14.0] - 2024-12-13
### Added
* Added support for the RG16f texture format and a selection mode for the texture format of the Space Warp motion vector texture for the Meta Quest feature. You can select the format for the Space Warp motion vector texture in Editor > Project Settings > XR Plug-in Management > OpenXR > Android tab > Meta Quest Support feature settings.
* Added the following extension methods for `XrResult`: `IsSuccess()`, `IsUnqualifiedSuccess()`, and `IsError()`, which you can use to more conveniently reason about `XrResult` values.
* Added new values to the `XrResult` enum to match the values present in the native `XrResult` type in OpenXR 1.1.36.
* Added support for locating the OpenXR loader for the Meta XR Simulator on OSX.
* Added new Optimize Multiview Render Regions settings option for Meta Quest devices. In the context of XR rendering, Multiview Render Regions enables the drivers to skip shader invocations (and rendering work) for screen areas outside of the user's view (such as the nasal regions that the user can't see within the headset). You can toggle on support for Multiview Render Regions in Editor > Project Settings > XR Plug-in Management > OpenXR > Android tab > Meta Quest Support feature settings. Note that Multiview Render Regions requires Symmetric Projection settings toggle turned on, and Render Mode set to Single Pass Instanced \ Multi-view. Multiview Render Regions is only supported in the Vulkan Graphics API, and it is activated at application start up.
* Added project validation warning to prevent user from using URP upscaling with XR.
### Deprecated
* Deprecated `XrResult.TimeoutExpored` and `XrResult.AndroidThreadSettingsdFailureKHR` and replaced them with correctly spelled enum values.
### Fixed
* Occlusion Mask vertices projected based on FOV.
## [1.13.2] - 2024-11-15
### Added
* Added UWP platform as one of the supported build targets for OpenXR Composition Layer feature.
### Fixed
* Fixed compiler errors when using experimental versions of the XR Composition Layers package (versions older than 1.0.0). You are required to use XR Composition Layers 1.0.0 or newer for OpenXR support.
## [1.13.1] - 2024-10-31
### Fixed
* Conformance Automation Feature: Removed assert for optional entry point xrSetInputDeviceVelocityUNITY.
## [1.13.0] - 2024-09-16
### Added
* Added Meta XR Simulator as runtime option for OpenXR. One can search for the `com.meta.xr.simulator` package to add the Open XR runtime to the dropdown list of available runtimes during Play Mode.
* Added a `Quest 3S` option to `Target Devices` in the Meta Quest Support settings. This specifies the application's support for Quest 3S devices within the Android manifest.
* Added `IUnityXRDisplay::CreateTexture` API to C# script so providers can access them for functionality.
* Added APIs to provide an alternative to the Input System: `OpenXRFeature.GetAction`, `OpenXRInput.GetActionHandle`, `OpenXRInput.SendHapticImpulse`, `OpenXRInput.StopHapticImpulse`, `OpenXRInput.TrySetControllerLateLatchAction`, and `OpenXRInput.GetActionIsActive`.
* Added a "Controller XRInput" sample to demonstrate how to access input data without the Input System.
* Added experimental support for XR Composition Layers support. Install the Unity [Composition Layer (com.unity.xr.compositionlayers)](https://docs.unity3d.com/Packages/com.unity.xr.compositionlayers@latest?subfolder=/changelog/CHANGELOG.html) package to use composition layers in an OpenXR project.
* Added support for the `XR_KHR_maintenance1` extension. This low-level extension provides support for new capabilities promoted in the OpenXR 1.1 standard, which may be needed for backwards compatibility for using new extensions in OpenXR loaders using the version 1.0 of the standard. You need to request this extension if your project will make use of OpenXR 1.1 extenstions that need this extension and are backwards compatible with loaders based on the 1.0 version of the OpenXR standard. If your project targets only the OpenXR 1.1 version, you don't need to request this extension. To use the `XR_KHR_maintenance1` extension, you must request it as part of your own [OpenXR feature definition](xref:openxr-features). Refer to [XR_KHR_maintenance1](https://registry.khronos.org/OpenXR/specs/1.1/html/xrspec.html#XR_KHR_maintenance1) for more information on the extension.
* Added OpenXR 1.1 Runtime support.
### Changed
* Added [Known Issue](xref:openxr-manual#known-issues) to documentation covering how OpenXR doesn't provide Acceleration or Angular Acceleration values for input devices, and these will always return 0.
* Added a validation rule requiring Multi-view to be enabled in order to enable Symmetric Projection.
* Implements the construction and maintenance of native composition layers in C# via our LayerProvider classes inheriting from OpenXRCustomLayerHandler.
* Changed OpenXR loader version to 1.1.36.
### Fixed
* Symmetric Projection was being gated behind foveation extensions being enabled. This wasn't necessary and that dependency has been removed.
* Fixed a bug that causes a user to need a validation rule to make OpenXR loader active.
* Fixed `m_BlendMode` from being overwritten whenever the `DisplaySubsystem` restarts.
* Fixed Metal API initialization.
* Fixed Custom Composition Layer Feature not showing up in the OpenXR feature setting UI after importing into project.
* Fixed a crash with composition layers in scene due to race condition.
## [1.12.1] - 2024-09-05
* Fixed rendering bug when rendering viewport scale < 1.
* Fixed issue where the Editor would hang when renaming and then viewing OpenXR Settings.
## [1.12.0] - 2024-08-01
### Added
* Add class `MetaQuestTouchPlusControllerProfile.QuestTouchPlusController` interaction profile to support Meta Quest Touch Plus Controllers.
* Added a validation rule to warn you that soft shadows can negatively affect performance for Microsoft HoloLens.
* Added a validation rule to infrom you to make the OpenXR Loader an active loader in XR Plugin Management if there are active OpenXR features in the OpenXR settings.
* Added `OpenXRSettings.autoColorSubmissionMode` boolean property to specify OpenXR to use a platform-supported color format in the display swapchain, or for you to manually set which format should OpenXR to use.
* Added `OpenXRSettings.colorSubmissionModes` array property to control the color format used by the OpenXR display swapchain. The available options can be chosen from the `OpenXRSettings.ColorSubmissionModeGroup` enum. OpenXR will use supported color formats by the platform, starting from the first option in the list. In case none of the color formats supplied is supported by the platform, an error will be thrown. If no color formats are assigned, the format used will be RGBA32.
* Added `Automatic Color Submission Mode` toggle and `Color Submission Modes` list to the OpenXR project settings tab, allowing you to manually specify the preferred color format to be used by the display swapchain. OpenXR will use supported color formats by the platform, starting from the first option in the list. In case none of the color formats supplied is supported by the platform, an error will be thrown. If no color formats are assigned, the format used will be RGBA32.
### Fixed
* Fixed sort order of OpenXR features listed based first on priority, then by name, preventing spurious changes in Settings files.
## [1.11.0] - 2024-05-01
### Added
* Added the `XrPerformanceSettings.SetPerformanceLevelHint` static method, which lets you send performance level suggestions to the runtime. These hints help an OpenXR runtime to optimize the use of hardware resources according to the application needs. Refer to [XR performance settings](xref:openxr-performance-settings#performance-settings-level-hints) for more information. This requires the [XR_EXT_performance_settings](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_performance_settings) extension is enabled in the OpenXR runtime.
* Added the `XrPerformanceSettings.OnXrPerformanceChangeNotification` event, which provides notifications from the OpenXR runtime when a device's thermal, rendering, or compositor performance state changes. The performance states include: `Normal`, `Warning`, and `Impaired`. Refer to [XR performance settings](xref:openxr-performance-settings#performance-settings-notifications) for more information. This requires the [XR_EXT_performance_settings](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_performance_settings) extension is enabled in the OpenXR runtime.
* Added a`Quest 3` option to the `Target Devices` set in the Meta Quest Support settings. This specifies the application's support for Quest 3 devices within the Android manifest.
* Added missing ButtonControl actions `pinch_ext`, `aim_activate_ext` and `grasp_ext` for Hand Interaction Profile.
* Added API `OpenXRUtility.ComputePoseToWorldSpace` to recalculate object position and rotation from tracking-space to world-space. Applicable for use cases such as teleporting.
* Added support for using Local Floor Reference Space in the OpenXR runtime. Useful in applications that require the user to be seated or in a standing fixed position.
* Added PreInit flags to allow users to disable the main frame buffer and use offscreen swapchain when using Vulkan on Android in the OpenXR settings.
* Added functional DX12 mock runtime support to the OpenXR package.
* Added `RegisterStatsDescriptor` method to the `OpenXRFeature` abstract class, which lets your OpenXR feature to register a new statistic that can be feed into and queried at runtime. This method is not thread safe.
* Added `SetStatAsFloat` method to the `OpenXRFeature` abstract class, which lets your OpenXR feature to feed a float value into a specific statistic that was previously registered using the `RegisterStatsDescriptor`. This method is thread safe.
* Added `SetStatAsUInt` method to the `OpenXRFeature` abstract class, which lets your OpenXR feature to feed an unsigned integer value into a specific statistic that was previously registered using the `RegisterStatsDescriptor`. This method is thread safe.
* Added the `OpenXRSettings.RefreshRecenterSpace` static method, which lets you regenerate the internal XR space used for recentering, without the need to wait until a recenter event is received by the OpenXR SDK. Note that this method does not perform a recenter event in any way, as this can only be done by the device runtime.
* Added Pre-pass Foveated Rendering for both d3d12 and Vulkan. This feature utilizes Fragment Density Mapping on Quest Devices and Fragment Shading Rate on PC to optimize rendering performance. Refer to [Foveated Rendering](xref:openxr-foveated-rendering) for more information.
* Added `OpenXRUtility.IsSessionFocused` to return if the current session is in the focused state.
* Added `OpenXRUtility.IsUserPresent` to return the change of user presence, such as when the user has taken off or put on an XR headset. If the system does not support user presence sensing, runtime assumes that the user is always present and IsUserPresent always returns True. If the system supports the sensing of user presence, returns true when detected the presence of a user and returns false when detected the absence of a user.
### Changed
* Changed tracking origin to use Local Floor in place of Floor by default.
* Changed delta time calculation to utilize OpenXR for frame estimation. Previously internal Unity mechanisms were used. This feature is currently disabled but will be available in the future.
* When retrieving input feature from [CommonUsages.userPresence](https://docs.unity3d.com/ScriptReference/XR.CommonUsages-userPresence.html), if XR_EXT_user_presence is supported by the current system, retrieved value will be the same as `OpenXRUtility.IsUserPresent`. If `XR_EXT_user_presence` is not supported, retrieved value will be based on `OpenXRUtility.IsSessionFocused`, which is the default return value before 1.11.0.
### Fixed
* Fixed Marshal to correctly read the number of bytes for booleans in C++.
* Fixed crash that occurs while cleaning up destroyed swapchains in OpenXR.
* Fixed Depth Texture flag disparity between the OpenXR and Oculus providers.
## [1.10.0] - 2024-01-26
### Added
* Added `OpenXRSettings.VulkanAdditionalGraphicsQueue` property to request at startup an additional Vulkan graphics queue in devices that require it. The setting can be enabled through the Project settings UI and build code.
* Added `Optimize Buffer Discards (Vulkan)` feature setting option within MetaQuestFeature.
* Added a new optional validation rule to switch to use InputSystem.Controls.StickControl instead of Vector2Control for thumbsticks. StickControl allows more input options for thumbstick-based control, such as acting as both a combined 2D vector, two independent axes or a four-way Dpad with 4 independent buttons.
### Changed
* Updated project validation rule for Meta Quest Feature - "Select Oculus Touch Interaction Profile or Meta Quest Pro Touch Interaction Profile to pair with." from error to warning to allow other interaction profiles to be enabled as well, like eye gaze or palm pose.
### Fixed
* Fixed Meta XR `Space Warp` feature crashing issue when trying to access the depth swapchain.
* Fixed Meta XR `Space Warp` depth subimage imageArrayIndex setup wrong issue for multiview render mode.
* Fixed a bug where Palm Pose won't work if the Eye Gaze Interaction Profile is added to the project.
* Fixed "The type 'AnalyticsResult' is defined in an assembly that is not referenced" error thrown.
* Fixed UnitySwapchain destructor to completely destroy swapchains to avoid memory leak.
* Fixed OpenXR Settings UI to not render settings on platforms that aren't supported.
* Fixed Android manifest entries were added when the feature was not enabled.
## [1.9.1] - 2023-10-19
### Added
* Implemented `InputSystem.customBindingPathValidators` interface to show UI warnings in the `InputAsset` Editor when added bindings to a disabled interaction profile and when none of the controller type interaction profiles are enabled, but added bindings using generic XRController.
* Added APIs `GetInteractionProfileType` and `GetDeviceLayoutName` to support binding path validator feature.
* Added API `TrySetControllerLateLatchAction` to support controller late latching. Also added MarkLateLatchNode.cs in Controller Sample for usages example.
* Added support for Meta XR feature `Symmetric Projection`, `Space Warp`, and `Eye Tracked Foveation`.
* Added the option to enable `Subsampled Layout` when creating a Vulkan swapchain.
* Added support for recentering Floor tracking origin using new API, `OpenXRSettings.SetAllowRecentering`. This static method allows the app to recenter the tracking origin space when requested by the runtime. Note that calling the method won't trigger a recenter event.
* Added support for Meta XR feature `System Splash Screen`.
* Added public API for MetaQuestFeature.forceRemoveInternetPermission
### Changed
* Updated Input System package dependency to 1.6.3.
* Updated XR management dependency to 4.4.0.
* Updated OpenXR loader to 1.0.29.
* Changed MockRuntime and its FeatureSet to public.
### Fixed
* Fixed incorrect XR Validation rules after regenerating the OpenXR package settings asset.
* Fixed analytics code being called when disabled.
* Fixed latency issue with controller poses.
* Fixed an XR_ERROR_SESSION_NOT_RUNNING error if xrRequestExitSession is called when the session is not running.
## [1.8.2] - 2023-07-18
### Added
* Added a new optional validation rule to recommend disabling Screen Space Ambient Occlusion render feature in UniversalRenderer assets to avoid significant performance overhead.
### Changed
* Removed `Windows Mixed Reality feature group` from Windows build target.
### Fixed
* Fixed issue that UWP player tries to initialize XR when "Initialize XR on Startup" is unchecked.
* Fixed `SetOutput Failed.` and `SetInput Failed.` log spamming issue when audio sources is not available.
* Fixed performance drop after headset becomes inactive.
* Fixed Hand Common Poses Interaction Profile and Palm Pose feature documentation links broken.
* Fixed Mock Runtime option toggles on accidentally after entering Play Mode.
* Fixed hand tracking position and rotation not being tracked with XR Hand device.
## [1.8.1] - 2023-06-09
### Added
* Added functionality in `OpenXRFeatureBuildHooks` exposing the BootConfig for reading/writing.
* Added `Force Remove Internet Permission` setting to the Meta Quest Feature settings, allowing to remove Internet permissions added automatically to the application manifest.
* Added class HPReverbG2ControllerProfile.ReverbG2Controller and a new interaction profile to support the HP Reverb G2 controllers.
* Added Hand Interaction Profile and added PalmPose and dpad EXT implementations.
### Changed
* Modified `ModifyAndroidManifestMeta` class to provide required Android manifest entries using a new internal XR system, instead of manually modifying the manifest file.
* Updated the IsTracked and TrackingState Input Features names with a Usage prefix to prevent name collisions.
* Updated OpenXR loader to 1.0.27.
### Fixed
* Fixed type `XrCompositionLayerPassthroughFB` not appearing in the runtime debugger.
* Fixed crash when deploying to Android on Unity 2023 due to using type `Activity` over `GameActivity`.
* Fixed issue on Android where screen captures only capture the view on one eye.
## [1.7.0] - 2023-02-21
### Added
* Added API `OpenXRRuntime.retryInitializationOnFormFactorErrors` to retry xrGetSystem during initialization if xrGetSystem returns a form factor error.
* Enable XR_META_performance_metrics. This enables performance stats for Meta Quest devices on OpenXR.
* Add class MetaQuestTouchProControllerProfile.QuestProTouchController new interaction profile to support Meta Quest pro controllers.
* Added ability for OpenXRFeature derived classes to add Awake() functions.
* Added API `OpenXRInput.GetActionIsActive` to check whether an InputAction has any bindings which are currently active.
* Added API `OpenXRInput.GetActionHandle` to get the action handle of an InputAction and returns 0 if not found.
### Changed
* Updated documentation for the Meta Quest feature.
### Fixed
* Fixed - Meta builds now don't include Bluetooth permissions in Android manifest by default when using Microphone class in script code.
* Fixed crash in OpenXR runtime debugger when cache size is set to 0.
* Fixed OpenXR project validation to check for correct versions of OpenGLES in Unity 2023 and up.
* Fixed crash when runtime reports an invalid view configuration from xrWaitFrame.
* Fixed - OpenXR plugin will only look up functions from supported and enabled extensions.
* Fixed GPU selection in multi-GPU scenarios.
## [1.6.0] - 2022-11-29
### Added
* Added `Meta Quest Feature` support for Android and deprecated previous `Oculus Quest Feature`. Also added a new validation rule to support new Meta Quest Feature migration.
* Added API `MetaQuestFeature.AddTargetDevice` to add additional target devices to the devices list in the MetaQuestFeatureEditor.
* Added Thumbrest Touch support in Oculus Touch Controller Interaction Profile.
* Added a new optional validation rule to switch to use InputSystem.XR.PoseControl instead of OpenXR.Input.PoseControl, which fixed PoseControl conflicts in InputSystem.XR and OpenXR.Input. Note: If opt in to use InputSystem.XR.PoseControl, `USE_INPUT_SYSTEM_POSE_CONTROL` will be added in Scripting Define Symbols under Player settings.
### Changed
* Updated Input System dependency to 1.4.4.
### Fixed
* Fixed issue where game window would show as black in URP.
* Fixed `InputDevice.TryGetHapticCapabilities` always returning True with OpenXR.
* Fixed repeated "Failed to restart OpenXR" warnings when no HMD is attached.
* Fixed invalid pose values getting populated when tracked flags are invalid.
* Fixed XR_SPACE_BOUNDS_UNAVAILABLE return code marked as Error in the log.
## [1.5.2] - 2022-09-08
### Added
* Added support for Android cross-vendor loader.
### Changed
* Updated Input System dependency to 1.4.2.
### Fixed
* Fixed `XRInputSubsystem.TryGetBoundaryPoints` returning inaccurate values. If you have guardian/boundary setup in the headset, `TryGetBoundaryPoints` will return a List<Vector3> of size 4 representing the four vertices of the Play Area rectangle, which is centered at the origin and edges corresponding to the X and Z axes of the provided space. Not all systems or spaces may support boundaries.
* Fixed an issue that controllers position not getting updated and stuck to the floor level when Oculus Integration Asset installed in the project.
* Fixed an issue that OpenXR libraries were included in build when OpenXR SDK is not enabled.
* Improved domain reload performance by removing unnecessary checks when entering Playmode.
## [1.5.1] - 2022-08-11
### Added
* Added generic Project Validation status in the **Project Settings** window under **XR Plug-in Management** if you have [XR Core Utilities](https://docs.unity3d.com/Packages/com.unity.xr.core-utils@latest) 2.1.0 or later installed. These results include the checks for all XR plug-ins that provide validation rules.
* Added API `OpenXRFeature.SetEnvironmentBlendMode` to set the current XR Environment Blend Mode if it is supported by the active runtime. If not supported, fall back to the runtime preference.
* Added API `OpenXRFeature.GetEnvironmentBlendMode` to return the current XR Environment Blend Mode.
* Added support for `XR_MSFT_holographic_windown_attachment` extension on UWP so that installing Microsoft Mixed Reality OpenXR Plug-in is no longer required if targeting HoloLens V2 devices. And removed corresponding project validator.
* Added support for `XR_FB_foveation`, `XR_FB_foveation_configuration`, `XR_FB_swapchain_update_state`, `XR_FB_foveation_vulkan` and `XR_FB_space_warp` extensions.
* Added ability to recover the application after Oculus Link was aborted and re-established. Attempt to restart every 5 seconds after Link disconnected.
* Added validation rule for duplicate settings in OpenXRPackageSettings.asset.
### Changed
* Updated Oculus Android manifest with focusAware, supportedDevices and headTracking tags added. Also added a new validation rule to check if Oculus target devices are selected.
* Updated OpenXR Loader to 1.0.23.
* Updated Input System dependency to 1.4.1.
### Fixed
* Fixed compilation errors on Game Core platforms where `ENABLE_VR` is not currently defined. Requires Input System 1.4.0 or newer.
* Fixed an issue that was causing Oculus Android Vulkan builds rendering broken after sleep / awake HMD.
* Fixed Oculus controllers tracking issues when both OpenXR package and Oculus package are installed in the project.
* Fixed an issue in Play Mode OpenXR Runtime selection that `Other` option would be reverted to `System Default` after entering and exiting playmode.
* Fixed a bug in `XR_VARJO_quad_views` support.
## [1.4.2] - 2022-05-12
### Fixed
* Fixed unnecessary destroying session on pause and resume.
## [1.4.1] - 2022-04-13
### Added
* Added runtime failures handling to completely shut down OpenXR when runtime error occurred.
* Added support to dynamically discover runtimes by registry key.
* Added logging for no MainCamera tag detected when depthSubmission mode enabled.
* Added console error logging if entering playmode on unsupported platforms.
* Added support to automatically open OpenXR project validator if any issues detected after package update.
* Added API `OpenXRFeature.GetViewConfigurationTypeForRenderPass`, which returns viewConfigurationType for the given renderPass index.
* Added pre-init support for UWP / WSA platform. Note: OpenXR got unchecked by upgrading to this version (only on UWP), but options chosen under `Features` remained as they were.
### Changed
* Updated OpenXR Loader to 1.0.20.
* Updated Render Mode naming to Single Pass Instanced / Multiview for Android platform.
* Updated Input System dependency to 1.3.0.
* Updated XR mirror view to be based on the occlusion mesh line loop data obtained from `xrGetVisibilityMaskKHR`.
### Fixed
* Fixed an issue that would cause failure to load OpenXR loader when non-ascii characters in project path.
* Fixed an editor crash issue when updating OpenXR package version and then enter Playmode.
* Fixed `EyeGaze` functionality not working in the `Controller` sample.
* Fixed Oculus `MenuButton` not being recognized in script.
* Fixed an issue that some OpenXR Editor settings not being serialized properly.
* Fixed `Failed to suggest bindings for interaction profile` console error spamming when a runtime doesn't support a certain interaction profile.
## [1.3.1] - 2021-11-17
### Changed
* Updated documentation link to 1.3.
* Updated Oculus Android manifest with intent-filter.
### Fixed
* Fixed an issue in `OpenXRRestarter` that would prevent a subsequent restart.
* Fixed an issue in `OpenXRRestarter` that would cause a restart to fail depending on where it was initiated in the stack.
* Fixed an issue in UWP that would prevent the main window from being rendered to when using remoting.
* Fixed incorrect negative values on controller linear velocities.
* Fixed a bug in HMD trackingState that would cause tracking state to flip back and forth between two states every frame.
## [1.3.0] - 2021-10-20
### Added
* Added API `OpenXRInput.SendHapticImpulse`
* Added API `OpenXRInput.StopHaptics`
* Added API `OpenXRInput.TryGetInputSourceName`
* Added event `OpenXRRuntime.wantsToRestart`
* Added event `OpenXRRuntime.wantsToQuit`
* Added support for `XR_OCULUS_audio_device_guid` extension.
* Added `Haptic` control to OpenXR Controller Profile layouts that can be bound to an action and used to trigger haptics using the new `OpenXRInput.SendHapticImpulse` API.
### Changed
* Improved `OpenXRFeatureSetManager.SetFeaturesFromEnabledFeatureSets` so that no internal methods are required after calling this.
* Updated `Controller` sample to improve the visuals and use the new APIs
### Fixed
* Fixed ARM32 crash when OpenXR API layers were present
* [ISSUE-1355859](https://issuetracker.unity3d.com/issues/xr-uwp-any-openxr-layer-will-crash-unityopenxr-dot-dll-on-hololens2-when-compiling-with-arm32)
* Fixed issue that would cause console errors if `OpenXRFeature.enable` was changed while the OpenXR Projects Settings windows was open.
* Fixed potential Android crash when shutting down.
* Fixed potential crash with `XR_MSFT_SECONDARY_VIEW_CONFIGURATION_EXTENSION_NAME`
* Fixed issue with alpha channel on Projection layer causing visual artifacts.
* [ISSUE-1338699](https://issuetracker.unity3d.com/issues/xr-openxr-a-black-background-is-rendered-in-hmd-when-using-solid-color-camera-clear-flags)
* [ISSUE-1349271](https://issuetracker.unity3d.com/issues/xr-sdk-openxr-post-processing-postexposure-effect-has-visual-artifacts)
* [ISSUE-1346455](https://issuetracker.unity3d.com/issues/xr-sdk-openxr-right-eye-contains-artifacts-when-taa-anti-aliasing-is-used-with-multi-pass-rendering-mode)
* [ISSUE-1336968](https://issuetracker.unity3d.com/issues/xr-openxr-oculus-post-processing-view-in-hmd-is-darker-and-sometimes-flickers-when-changing-depth-of-field-focus-distance)
* [ISSUE-1338696](https://issuetracker.unity3d.com/issues/xr-sdk-openxr-black-edges-are-rendered-on-the-game-objects-when-fxaa-anti-aliasing-is-used)
* Fixed bug that caused Vulkan support on Oculus to stop working.
* Fixed missing usages on `HoloLensHand` layout.
* Fixed vulkan shared depth buffer on versions `2021.2.0b15` and `2022.1.0a8` or higher.
## [1.2.8] - 2021-07-29
### Fixed
* Fixed an issue that was causing Oculus Android OpenGL builds to stop working after v31 of the oculus software was installed.
* Fixed a bug that would cause Asset Bundles to fail building in some circumstances when OpenXR was included in the project.
* Fixed a crash that would occur if XR was shut down from within a Feature callback.
* Fixed a bug that was causing duplicate entries in the OpenXR Package Settings file.
* Fixed a bug causing angular velocities on both the HMD and controllers to have the wrong sign when compared to the other Unity XR plugins
## [1.2.3] - 2021-06-17
### Added
* Ensured a deterministic order of features within the OpenXR Settings
### Changed
* Updated OpenXR Loader to 1.0.17
* Changed `feature set` text to `feature group` in the top level XR-Management list
### Fixed
* Fixed missing haptic output on HTC Vive controller profile
* Fixed bug that caused `ThumbstickTouched` binding on the `ValveIndex` controller profile to not work.
* Fixed issue that would cause the app to not exit when closed by the runtime
## [1.2.2] - 2021-06-01
### Added
* Editor runtime override will no longer change the runtime for standalone builds executed using `Build and Run`.
### Changed
* Renamed `Feature Sets` to `Feature Groups` in the UI.
### Removed
* Removed unnecessary build hook for `EyeGaze` that was causing incorrect capabilities to be set on `HoloLens2`.
### Fixed
* Fixed a bug when using SteamVR runtime that would cause the view to stop rendering and input to stop tracking if the main thread stalled for too long.
* Fixed bug with feature sets that could cause the XR Management check box to be out of sync with the checkbox on the OpenXR Settings page.
* Fixed bug with HTC Vive controller profile that caused the `aim` and `grip` poses to be identical.
## [1.2.0] - 2021-05-06
### Added
* Enabled Android build target for Oculus Quest via the `Oculus Quest Support` feature.
* OpenXR Settings UI reworked to make managing features and interaction profiles easier.
* Added menu item to open Project Validation window (`Window > XR > OpenXR > Project Validation`).
* Project validation window now supports manual fixes for an issue.
* Project validation window now supports optional help links for an issue.
* Added `OpenXRFeature.OnEnableChanged` method to give features a chance to handle their enabled state changing.
* Added `IPackageSettings.GetFeatures` method that returns all features of a given type from all build targets.
### Removed
* Removed `experimental` text from OpenXR plugin help icon.
* Removed `Linear` color space restriction for all build targets and graphics apis except OpenGLES.
### Fixed
* Fixed bug with haptics that caused `XRControllerWithRumble.SendImpulse` to not work with `OpenXR`.
* Fixed bug that could cause some interaction profile device layouts to not be registered on startup.
## [1.1.1] - 2021-04-06
### Added
* Oculus controller profile now exposes both grip and aim poses.
* Added support for `XR_VARJO_QUAD_VIEWS` extension
* Added `XR_COMPOSITION_LAYER_UNPREMULTIPLIED_ALPHA_BIT` and `XR_COMPOSITION_LAYER_BLEND_TEXTURE_SOURCE_ALPHA_BIT` bits to the composition layer flags
* Added `XrSecondaryViewConfigurationSwapchainCreateInfoMSFT` to to `XrSwapchainCreateInfo` when using a secondary view
* MockRuntime First Person Observer View support
* MockRuntime input support
* MockRuntime vulkan_enable2 support
* MockRuntime d3d11_enable support
### Changed
* `OpenXRSettings.renderMode` and `OpenXrSettings.depthSubmissionMode` can now be changed via script outside of play mode.
### Fixed
* Fixed issue where OpenXR layouts were not visible in the InputSystem bindings dialog.
* Fix for managed stripping levels of Medium and High
* Fixed bugs in `XR_KHR_VULKAN_ENABLE2` extension support
## [1.0.2] - 2021-02-04
### Fixed
* Resolve further release verification issues.
## [1.0.1] - 2021-02-03
### Fixed
* Resolve release verification issues.
## [1.0.0] - 2021-01-27
### Added
* Runtime Debugger to allow for the inspection of OpenXR calls that occur while OpenXR is actively running.
* XR Plug-In Management dependency update to 4.0.1
* Input System dependency updated to 1.0.2
## [0.1.2-preview.3] - 2021-01-19
### Added
* Implemented `XR_KHR_loader_init` and `XR_KHR_loader_init_android`.
* Added support for `XR_KHR_vulkan_enable2` alongside `XR_KHR_vulkan_enable`.
### Changed
* Updated dependency of `com.unity.xr.management` from `4.0.0-pre.2` to `4.0.0-pre.3`.
## [0.1.2-preview.2] - 2021-01-05
### Fixed
* Fix publishing pipeline.
## [0.1.2-preview.1] - 2020-12-18
### Changed
* Minor documentation getting started tweaks.
* Minor diagnostic logging tweaks.
### Fixed
* Fixed package errors when Analytics package is absent (case 1300418).
* Fixed tracking origin issue which was causing wrong camera height (case 1300457).
* Fixed issue where large portions of the world were incorrectly culled at certain camera orientations.
* Fixed potential error message when clicking `Fix All` in OpenXR Project Validation window.
* Fixed an issue with sample importing.
## [0.1.1-preview.1] - 2020-12-16
### This is the first release of *OpenXR Plugin \<com.unity.xr.openxr\>*.

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c08abd10a5a23472bbd33729ecd14462
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 20fabbec025701c4b82246a74e8d94fd
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,218 @@
using System;
using System.Runtime.InteropServices;
using UnityEngine.XR.OpenXR.NativeTypes;
#if UNITY_EDITOR
using UnityEditor.XR.OpenXR.Features;
#endif
namespace UnityEngine.XR.OpenXR.Features.ConformanceAutomation
{
/// <summary>
/// This OpenXRFeature implements XR_EXT_conformance_automation.
/// See https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_conformance_automation
/// </summary>
#if UNITY_EDITOR
[OpenXRFeature(UiName = "Conformance Automation",
Hidden = true,
BuildTargetGroups = new[] {UnityEditor.BuildTargetGroup.Standalone, UnityEditor.BuildTargetGroup.Android, UnityEditor.BuildTargetGroup.WSA },
Company = "Unity",
Desc = "The XR_EXT_conformance_automation allows conformance test and runtime developers to provide hints to the underlying runtime as to what input the test is expecting. This enables runtime authors to automate the testing of their runtime conformance.",
DocumentationLink = Constants.k_DocumentationURL,
OpenxrExtensionStrings = "XR_EXT_conformance_automation",
Version = "0.0.1",
FeatureId = featureId)]
#endif
public class ConformanceAutomationFeature : OpenXRFeature
{
/// <summary>
/// The feature id string. This is used to give the feature a well known id for reference.
/// </summary>
public const string featureId = "com.unity.openxr.feature.conformance";
private static ulong xrInstance = 0ul;
private static ulong xrSession = 0ul;
/// <inheritdoc/>
protected internal override bool OnInstanceCreate(ulong instance)
{
if (!OpenXRRuntime.IsExtensionEnabled("XR_EXT_conformance_automation"))
{
Debug.LogError("XR_EXT_conformance_automation is not enabled. Disabling ConformanceAutomationExt");
return false;
}
xrInstance = instance;
xrSession = 0ul;
initialize(xrGetInstanceProcAddr, xrInstance);
return true;
}
/// <inheritdoc/>
protected internal override void OnInstanceDestroy(ulong xrInstance)
{
base.OnInstanceDestroy(xrInstance);
ConformanceAutomationFeature.xrInstance = 0ul;
}
/// <inheritdoc/>
protected internal override void OnSessionCreate(ulong xrSessionId)
{
ConformanceAutomationFeature.xrSession = xrSessionId;
base.OnSessionCreate(xrSession);
}
/// <inheritdoc/>
protected internal override void OnSessionDestroy(ulong xrSessionId)
{
base.OnSessionDestroy(xrSessionId);
ConformanceAutomationFeature.xrSession = 0ul;
}
/// <summary>
/// Drive the xrSetInputDeviceActiveEXT function of the XR_EXT_conformance_automation.
/// See https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_conformance_automation
/// </summary>
/// <param name="interactionProfile">An OpenXRPath that specifies the OpenXR Interaction Profile of the value to be changed (e.g. /interaction_profiles/khr/simple_controller).</param>
/// <param name="topLevelPath">An OpenXRPath that specifies the OpenXR User Path of the value to be changed (e.g. /user/hand/left).</param>
/// <param name="isActive">A boolean that specifies the desired state of the target.</param>
/// <returns>Returns true if the state is set successfully, or false if there was an error.</returns>
public static bool ConformanceAutomationSetActive(string interactionProfile, string topLevelPath, bool isActive)
{
return xrSetInputDeviceActiveEXT(
xrSession,
StringToPath(interactionProfile),
StringToPath(topLevelPath),
isActive);
}
/// <summary>
/// Drive the xrSetInputDeviceStateBoolEXT function of the XR_EXT_conformance_automation.
/// See https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_conformance_automation
/// </summary>
/// <param name="topLevelPath">An OpenXRPath that specifies the OpenXR User Path of the value to be changed (e.g. /user/hand/left).</param>
/// <param name="inputSourcePath">An OpenXRPath that specifies the full path of the input component whose state you wish to set (e.g. /user/hand/left/input/select/click).</param>
/// <param name="state">A boolean that specifies the desired state of the target.</param>
/// <returns>Returns true if the state is set successfully, or false if there was an error.</returns>
public static bool ConformanceAutomationSetBool(string topLevelPath, string inputSourcePath, bool state)
{
return xrSetInputDeviceStateBoolEXT(
xrSession,
StringToPath(topLevelPath),
StringToPath(inputSourcePath),
state);
}
/// <summary>
/// Drive the xrSetInputDeviceStateFloatEXT function of the XR_EXT_conformance_automation.
/// See https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_conformance_automation
/// </summary>
/// <param name="topLevelPath">>An OpenXRPath that specifies the OpenXR User Path of the value to be changed (e.g. /user/hand/left).</param>
/// <param name="inputSourcePath">An OpenXRPath that specifies the full path of the input component whose state you wish to set (e.g. /user/hand/left/input/select/click).</param>
/// <param name="state">A float that specifies the desired state of the target.</param>
/// <returns>Returns true if the state is set successfully, or false if there was an error.</returns>
public static bool ConformanceAutomationSetFloat(string topLevelPath, string inputSourcePath, float state)
{
return xrSetInputDeviceStateFloatEXT(
xrSession,
StringToPath(topLevelPath),
StringToPath(inputSourcePath),
state);
}
/// <summary>
/// Drive the xrSetInputDeviceStateVector2fEXT function of the XR_EXT_conformance_automation.
/// See https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_conformance_automation
/// </summary>
/// <param name="topLevelPath">An OpenXRPath that specifies the OpenXR User Path of the value to be changed (e.g. /user/hand/left).</param>
/// <param name="inputSourcePath">An OpenXRPath that specifies the full path of the input component whose state you wish to set (e.g. /user/hand/left/input/select/click).</param>
/// <param name="state">A Vector2 that specifies the desired state of the target.</param>
/// <returns>Returns true if the state is set successfully, or false if there was an error.</returns>
public static bool ConformanceAutomationSetVec2(string topLevelPath, string inputSourcePath, Vector2 state)
{
return xrSetInputDeviceStateVector2fEXT(
xrSession,
StringToPath(topLevelPath),
StringToPath(inputSourcePath),
new XrVector2f(state));
}
/// <summary>
/// Drive the xrSetInputDeviceLocationEXT function of the XR_EXT_conformance_automation.
/// See https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_conformance_automation
/// </summary>
/// <param name="topLevelPath">An OpenXRPath that specifies the OpenXR User Path of the value to be changed (e.g. /user/hand/left).</param>
/// <param name="inputSourcePath">An OpenXRPath that specifies the full path of the input component whose state you wish to set (e.g. /user/hand/left/input/select/click).</param>
/// <param name="position">A Vector3 that specifies the desired state of the target.</param>
/// <param name="orientation">A Quaternion that specifies the desired state of the target.</param>
/// <returns>Returns true if the state is set successfully, or false if there was an error.</returns>
public static bool ConformanceAutomationSetPose(string topLevelPath, string inputSourcePath, Vector3 position, Quaternion orientation)
{
return xrSetInputDeviceLocationEXT(
xrSession,
StringToPath(topLevelPath),
StringToPath(inputSourcePath),
GetCurrentAppSpace(),
new XrPosef(position, orientation));
}
/// <summary>
/// Set the angular and linear velocity of a pose
/// </summary>
/// <param name="topLevelPath">An OpenXRPath that specifies the OpenXR User Path of the value to be changed (e.g. /user/hand/left).</param>
/// <param name="inputSourcePath">An OpenXRPath that specifies the full path of the input component whose state you wish to set (e.g. /user/hand/left/input/select/click).</param>
/// <param name="linearValid">True if the linear velocity is valid</param>
/// <param name="linear">Linear velocity value</param>
/// <param name="angularValid">True if the angular velocity is valid</param>
/// <param name="angular">Angular velocity value</param>
/// <returns>true if the velocity is set successfully, or false if there was an error.</returns>
public static bool ConformanceAutomationSetVelocity(string topLevelPath, string inputSourcePath, bool linearValid, Vector3 linear, bool angularValid, Vector3 angular)
{
return xrSetInputDeviceVelocityUNITY(
xrSession,
StringToPath(topLevelPath),
StringToPath(inputSourcePath),
linearValid,
new XrVector3f(linear),
angularValid,
new XrVector3f(-1.0f * angular) // Angular velocity is multiplied by -1 in the OpenXR plugin so it must be negated here as well
);
}
// Dll imports
private const string ExtLib = "ConformanceAutomationExt";
/// <summary>
/// Set up function pointers for xrSetInputDevice... functions.
/// </summary>
/// <param name="xrGetInstanceProcAddr">This is an IntPtr to the current OpenXR process address.</param>
/// <param name="xrInstance">This is a ulong handle for the current OpenXR xrInstance.</param>
[DllImport(ExtLib, EntryPoint = "script_initialize")]
private static extern void initialize(IntPtr xrGetInstanceProcAddr, ulong xrInstance);
[DllImport(ExtLib, EntryPoint = "script_xrSetInputDeviceActiveEXT")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool xrSetInputDeviceActiveEXT(ulong xrSession, ulong interactionProfile, ulong topLevelPath, [MarshalAs(UnmanagedType.I1)] bool isActive);
[DllImport(ExtLib, EntryPoint = "script_xrSetInputDeviceStateBoolEXT")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool xrSetInputDeviceStateBoolEXT(ulong xrSession, ulong topLevelPath, ulong inputSourcePath, [MarshalAs(UnmanagedType.I1)] bool state);
[DllImport(ExtLib, EntryPoint = "script_xrSetInputDeviceStateFloatEXT")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool xrSetInputDeviceStateFloatEXT(ulong xrSession, ulong topLevelPath, ulong inputSourcePath, float state);
[DllImport(ExtLib, EntryPoint = "script_xrSetInputDeviceStateVector2fEXT")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool xrSetInputDeviceStateVector2fEXT(ulong xrSession, ulong topLevelPath, ulong inputSourcePath, XrVector2f state);
[DllImport(ExtLib, EntryPoint = "script_xrSetInputDeviceLocationEXT")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool xrSetInputDeviceLocationEXT(ulong xrSession, ulong topLevelPath, ulong inputSourcePath, ulong space, XrPosef pose);
[DllImport(ExtLib, EntryPoint = "script_xrSetInputDeviceVelocityUNITY")]
[return: MarshalAs(UnmanagedType.U1)]
private static extern bool xrSetInputDeviceVelocityUNITY(ulong xrSession, ulong topLevelPath, ulong inputSourcePath, [MarshalAs(UnmanagedType.I1)] bool linearValid, XrVector3f linear, [MarshalAs(UnmanagedType.I1)] bool angularValid, XrVector3f angular);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 486b5e28864f9a94b979b9620ce5006d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,125 @@
#include "IUnityInterface.h"
#include "XR/IUnityXRTrace.h"
#include "openxr/openxr.h"
#include "openxr/openxr_reflection.h"
#include <cassert>
#include <cstring>
#include <string>
#include "enums_to_string.h"
#define CHECK_XRCMD(x) \
{ \
auto ret = x; \
assert(ret == XR_SUCCESS); \
}
typedef XrResult(XRAPI_PTR* PFN_xrSetInputDeviceVelocityUNITY)(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, bool linearValid, XrVector3f linear, bool angularValid, XrVector3f angular);
// OpenXR runtime functions
PFN_xrSetInputDeviceActiveEXT unity_xrSetInputDeviceActiveEXT = nullptr;
PFN_xrSetInputDeviceStateBoolEXT unity_xrSetInputDeviceStateBoolEXT = nullptr;
PFN_xrSetInputDeviceStateFloatEXT unity_xrSetInputDeviceStateFloatEXT = nullptr;
PFN_xrSetInputDeviceStateVector2fEXT unity_xrSetInputDeviceStateVector2fEXT = nullptr;
PFN_xrSetInputDeviceLocationEXT unity_xrSetInputDeviceLocationEXT = nullptr;
PFN_xrSetInputDeviceVelocityUNITY unity_xrSetInputDeviceVelocityUNITY = nullptr;
// Trace for Debug
static IUnityXRTrace* s_Trace = nullptr;
// XR_EXT_conformance_automation functions
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_xrSetInputDeviceActiveEXT(XrSession session, XrPath interactionProfile, XrPath topLevelPath, XrBool32 isActive)
{
if (nullptr == unity_xrSetInputDeviceActiveEXT)
return false;
return XR_SUCCESS == unity_xrSetInputDeviceActiveEXT(session, interactionProfile, topLevelPath, isActive);
}
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_xrSetInputDeviceStateBoolEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrBool32 state)
{
if (nullptr == unity_xrSetInputDeviceStateBoolEXT)
return false;
XrResult result = unity_xrSetInputDeviceStateBoolEXT(session, topLevelPath, inputSourcePath, state);
std::string traceString = "[ConformanceAutomationExt] - script_xrSetInputDeviceStateBoolEXT XrResult is ";
char resultString[256];
strcpy(resultString, to_string(result));
traceString = traceString + resultString;
traceString = traceString + "\n";
XR_TRACE_LOG(s_Trace, traceString.c_str());
return XR_SUCCESS == result;
}
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_xrSetInputDeviceStateFloatEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, float state)
{
if (nullptr == unity_xrSetInputDeviceStateFloatEXT)
return false;
return XR_SUCCESS == unity_xrSetInputDeviceStateFloatEXT(session, topLevelPath, inputSourcePath, state);
}
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_xrSetInputDeviceStateVector2fEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrVector2f state)
{
if (nullptr == unity_xrSetInputDeviceStateVector2fEXT)
return false;
return XR_SUCCESS == unity_xrSetInputDeviceStateVector2fEXT(session, topLevelPath, inputSourcePath, state);
}
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_xrSetInputDeviceLocationEXT(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, XrSpace space, XrPosef pose)
{
if (nullptr == unity_xrSetInputDeviceLocationEXT)
return false;
return XR_SUCCESS == unity_xrSetInputDeviceLocationEXT(session, topLevelPath, inputSourcePath, space, pose);
}
extern "C" bool UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_xrSetInputDeviceVelocityUNITY(XrSession session, XrPath topLevelPath, XrPath inputSourcePath, bool linearValid, XrVector3f linear, bool angularValid, XrVector3f angular)
{
if (nullptr == unity_xrSetInputDeviceVelocityUNITY)
return false;
return XR_SUCCESS == unity_xrSetInputDeviceVelocityUNITY(session, topLevelPath, inputSourcePath, linearValid, linear, angularValid, angular);
}
// Init
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
script_initialize(PFN_xrGetInstanceProcAddr xrGetInstanceProcAddr, XrInstance instance)
{
XR_TRACE_LOG(s_Trace, "[ConformanceAutomationExt] - script_initialize starting");
CHECK_XRCMD(xrGetInstanceProcAddr(instance, "xrSetInputDeviceActiveEXT", (PFN_xrVoidFunction*)&unity_xrSetInputDeviceActiveEXT));
CHECK_XRCMD(xrGetInstanceProcAddr(instance, "xrSetInputDeviceStateBoolEXT", (PFN_xrVoidFunction*)&unity_xrSetInputDeviceStateBoolEXT));
CHECK_XRCMD(xrGetInstanceProcAddr(instance, "xrSetInputDeviceStateFloatEXT", (PFN_xrVoidFunction*)&unity_xrSetInputDeviceStateFloatEXT));
CHECK_XRCMD(xrGetInstanceProcAddr(instance, "xrSetInputDeviceStateVector2fEXT", (PFN_xrVoidFunction*)&unity_xrSetInputDeviceStateVector2fEXT));
CHECK_XRCMD(xrGetInstanceProcAddr(instance, "xrSetInputDeviceLocationEXT", (PFN_xrVoidFunction*)&unity_xrSetInputDeviceLocationEXT));
// Do not assert on this function since some runtimes may not have implemented it
xrGetInstanceProcAddr(instance, "xrSetInputDeviceVelocityUNITY", (PFN_xrVoidFunction*)&unity_xrSetInputDeviceVelocityUNITY);
XR_TRACE_LOG(s_Trace, "[ConformanceAutomationExt] - script_initialize complete");
}
// UnityPlugin events
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginLoad(IUnityInterfaces* unityInterfaces)
{
s_Trace = unityInterfaces->Get<IUnityXRTrace>();
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API
UnityPluginUnload()
{
}

View File

@@ -0,0 +1,15 @@
{
"name": "Unity.XR.OpenXR.Features.ConformanceAutomation",
"references": [
"GUID:4847341ff46394e83bb78fbd0652937e"
],
"includePlatforms": [],
"excludePlatforms": [],
"allowUnsafeCode": false,
"overrideReferences": false,
"precompiledReferences": [],
"autoReferenced": true,
"defineConstraints": [],
"versionDefines": [],
"noEngineReferences": false
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: c8303d49cf73f7a4e9390d229bc0aaab
AssemblyDefinitionImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6e07c765742f4790a3c5b3e51375245d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 59e9388ff1604721928621cf5482a9ff
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
fileFormatVersion: 2
guid: 790fc22305914e66b3b66053af02b995
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 1
settings:
CPU: ARM64
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f1e1b9737825428da458a59e09e27407
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,82 @@
fileFormatVersion: 2
guid: 27938c35a7e243e8859d2de605125261
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
'': Any
second:
enabled: 0
settings:
Exclude Android: 0
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
- first:
Android: Android
second:
enabled: 1
settings:
CPU: X86_64
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 81b6069f0dbd4b949b4a0155a6e70d3c
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

Binary file not shown.

View File

@@ -0,0 +1,92 @@
fileFormatVersion: 2
guid: 8025489b05554b7aaec001a49e0b4e1a
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 1
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 1
Exclude iOS: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: OSX
- first:
Facebook: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Facebook: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: AnyCPU
- first:
iPhone: iOS
second:
enabled: 0
settings:
AddToEmbeddedBinaries: false
CPU: AnyCPU
CompileFlags:
FrameworkDependencies:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 4d3d406b2c614fdb835b0fcf33a150ba
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 8029bfc4f4824001a5a5aa64855a6054
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 79938ba5061f4de58df1f0aa7771cb8f
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: ARM
DontProcess: false
PlaceholderPath:
SDK: UWP
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 351e51add52a435f84348ede39721066
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 5e6c63ddb3ec470d8646e72fc9be1bff
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: ARM64
DontProcess: false
PlaceholderPath:
SDK: UWP
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 28fe6daa1d234417b642b5d75bbeca67
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 487d9d93fd3e41af846abd1136cc19b7
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 1
Exclude Linux64: 1
Exclude OSXUniversal: 1
Exclude Win: 1
Exclude Win64: 1
Exclude WindowsStoreApps: 0
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 0
settings:
CPU: AnyCPU
DefaultValueInitialized: true
OS: AnyOS
- first:
Standalone: Linux64
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: OSXUniversal
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 0
settings:
CPU: None
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 1
settings:
CPU: X64
DontProcess: false
PlaceholderPath:
SDK: UWP
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: eaa1223c09df4ed2b4f9525a54447409
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 97e5e4703eab45c4a12b9c99c67c99b5
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
fileFormatVersion: 2
guid: 89b15975e7984305943a56e76e66f173
PluginImporter:
externalObjects: {}
serializedVersion: 2
iconMap: {}
executionOrder: {}
defineConstraints: []
isPreloaded: 0
isOverridable: 1
isExplicitlyReferenced: 0
validateReferences: 1
platformData:
- first:
: Any
second:
enabled: 0
settings:
Exclude Android: 1
Exclude Editor: 0
Exclude Linux64: 0
Exclude OSXUniversal: 0
Exclude Win: 1
Exclude Win64: 0
Exclude WindowsStoreApps: 1
- first:
Android: Android
second:
enabled: 0
settings:
CPU: ARMv7
- first:
Any:
second:
enabled: 0
settings: {}
- first:
Editor: Editor
second:
enabled: 1
settings:
CPU: x86_64
DefaultValueInitialized: true
OS: Windows
- first:
Standalone: Linux64
second:
enabled: 1
settings:
CPU: x86_64
- first:
Standalone: OSXUniversal
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Standalone: Win
second:
enabled: 0
settings:
CPU: None
- first:
Standalone: Win64
second:
enabled: 1
settings:
CPU: AnyCPU
- first:
Windows Store Apps: WindowsStoreApps
second:
enabled: 0
settings:
CPU: AnyCPU
DontProcess: false
PlaceholderPath:
SDK: AnySDK
ScriptingBackend: AnyScriptingBackend
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,21 @@
* [About Unity OpenXR](index.md)
* [Project Configuration](project-configuration.md)
* [OpenXR Features](features.md)
* [Meta Quest Support](features/metaquest.md)
* [Foveated Rendering](features/foveatedrendering.md)
* [XR Performance Settings](features/performance-settings.md)
* [Multiview Render Regions](features/multiviewrenderregions.md)
* [OpenXR Input](input.md)
* [Microsoft Mixed Reality Motion Controller Profile](features/microsoftmotioncontrollerprofile.md)
* [Oculus Touch Controller Profile](features/oculustouchcontrollerprofile.md)
* [HTC Vive Controller Profile](features/htcvivecontrollerprofile.md)
* [Valve Index Controller Profile](features/valveindexcontrollerprofile.md)
* [Khronos Simple Controller Profile](features/khrsimplecontrollerprofile.md)
* [Eye Gaze Interaction](features/eyegazeinteraction.md)
* [Microsoft Hand Interaction](features/microsofthandinteraction.md)
* [Meta Quest Touch Pro Controller Profile](features/metaquesttouchprocontrollerprofile.md)
* [HP Reverb G2 Controller Profile](features/hpreverbg2controllerprofile.md)
* [Hand Interaction Profile](features/handinteractionprofile.md)
* [DPad Interaction](features/dpadinteraction.md)
* [Palm Pose Interaction](features/palmposeinteraction.md)
* [Hand Common Poses Interaction](features/handcommonposesinteraction.md)

View File

@@ -0,0 +1,208 @@
---
uid: openxr-features
---
# OpenXR Features
OpenXR is an extensible API that can be extended with new features. To facilitate this within the Unity ecosystem, the Unity OpenXR provider offers a feature extension mechanism.
## Feature Management
![feature-ui](images/openxr-features.png)
You can manage features from the **Project Settings &gt; XR Plug-in Management &gt; OpenXR** window.
To enable or disable a feature, select or clear the checkbox next to it. Unity doesn't execute disabled features at runtime, and doesn't deploy any of the feature's native libraries with the Player build. To configure additional build-time properties specific to each feature, click the gear icon to the right of the feature.
All of the information in this window is populated via the `OpenXRFeatureAttribute` described below.
**Feature Groups** group a number of different **features** together to allow you to configure them simultaneously, which might offer a better development experience. For more information, see the [Defining a feature group](#defining-a-feature-group) section on this page.
## Defining a feature
Unity OpenXR features are defined and executed in C#. C# can call to a custom native plugin if desired. The feature can live somewhere in the user's project or in a package, and it can include any Assets that a normal Unity project would use.
A feature must override the `OpenXRFeature` ScriptableObject class. There are several methods that you can override on the `OpenXRFeature` class in order to do things like intercepting native OpenXR calls, obtaining the `xrInstance` and `xrSession` handles, starting Unity subsystems, etc.
A feature can add public fields for user configuration at build time. Unity renders these fields via a `PropertyDrawer` in the feature UI, and you can override them. Your feature can access any of the set values at runtime.
A feature must also provide an `OpenXRFeature` attribute when running in the Editor.
```c#
#if UNITY_EDITOR
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "Example Intercept Create Session",
BuildTargetGroups = new []{BuildTargetGroup.Standalone, BuildTargetGroup.WSA},
Company = "Unity",
Desc = "Example feature extension showing how to intercept a single OpenXR function.",
DocumentationLink = "https://docs.unity3d.com/Packages/com.unity.xr.openxr@0.1/manual/index.html",
OpenxrExtensionStrings = "XR_test", // this extension doesn't exist, a log message will be printed that it couldn't be enabled
Version = "0.0.1",
FeatureId = featureId)]
#endif
public class InterceptCreateSessionFeature : OpenXRFeature
{
/// <summary>
/// The feature id string. This is used to give the feature a well known id for reference.
/// </summary>
public const string featureId = "com.unity.openxr.feature.example.intercept";
}
```
Unity uses this information at build time, either to build the Player or to display it to the user in the UI.
## Defining a feature group
Unity OpenXR allows you to define a feature group you can use to enable or disable a group of features at the same time. This way, you don't need to access the **Feature** section in **Project Settings &gt; XR Plug-in Management &gt; OpenXR** window to enable or disable features.
Declare a feature group through the definition of one or more `OpenXRFeatureSetAttribute` declarations in your code. You can place the attribute anywhere because the feature group functionality only depends on the attribute existing and not on the actual class it's declared on.
```c#
[OpenXRFeatureSet(
FeatureIds = new string[] { // The list of features that this feature group is defined for.
EyeGazeInteraction.featureId,
KHRSimpleControllerProfile.featureId,
"com.mycompany.myprovider.mynewfeature",
},
UiName = "Feature_Set_Name",
Description = "Feature group that allows for setting up the best environment for My Company's hardware.",
// Unique ID for this feature group
FeatureSetId = "com.mycompany.myprovider.mynewfeaturegroup",
SupportedBuildTargets = new BuildTargetGroup[]{ BuildTargetGroup.Standalone, BuildTargetGroup.Android }
)]
class MyCompanysFeatureSet
{}
```
You can configure feature groups in the **XR Plug-in Management** plug-in selection window. When you select the **OpenXR** plug-in from this window, the section under the plug-in displays the groups of features available. Not all feature groups are configurable. Some require you to install third-party definitions. The window displays information on where to get the required packages if needed.
### Enabling OpenXR spec extension strings
Unity will attempt to enable any extension strings listed in `OpenXRFeatureAttribute.OpenxrExtensionStrings` (separated via spaces) on startup. Your feature can check the enabled extensions in order to see if the requested extension was enabled (via `OpenXRRuntime.IsExtensionEnabled`).
```c#
protected virtual bool OnInstanceCreate(ulong xrInstance)
{
if (!OpenXRRuntime.IsExtensionEnabled("XR_UNITY_mock_driver"))
{
Debug.LogWarning("XR_UNITY_mock_driver is not enabled, disabling Mock Driver.");
// Return false here to indicate the system should disable your feature for this execution.
// Note that if a feature is marked required, returning false will cause the OpenXRLoader to abort and try another loader.
return false;
}
// Initialize your feature, check version to make sure you are compatible with it
if(OpenXRRuntime.GetExtensionVersion("XR_UNITY_mock_driver") < 100)
return false;
return true;
}
```
### OpenXRFeature call order
The `OpenXRFeature` class has a number of methods that your method can override. Implement overrides to get called at specific points in the OpenXR application lifecycle.
#### Bootstrapping
`HookGetInstanceProcAddr`
This is the first callback invoked, giving your feature the ability to hook native OpenXR functions.
#### Initialize
`OnInstanceCreate => OnSystemChange => OnSubsystemCreate => OnSessionCreate`
The initialize sequence allows features to initialize Unity subsystems in the Loader callbacks and execute them when specific OpenXR resources are created or queried.
#### Start
`OnFormFactorChange => OnEnvironmentBlendModeChange => OnViewConfigurationTypeChange => OnSessionBegin => OnAppSpaceChange => OnSubsystemStart`
The Start sequence allows features to start Unity subsystems in the Loader callbacks and execute them when the session is created.
#### Gameloop
Several: `OnSessionStateChange`
`OnSessionBegin`
Maybe: `OnSessionEnd`
Callbacks during the gameloop can react to session state changes.
#### Stop
`OnSubsystemStop => OnSessionEnd`
#### Shutdown
`OnSessionExiting => OnSubsystemDestroy => OnAppSpaceChange => OnSessionDestroy => OnInstanceDestroy`
### Build Time Processing
A feature can inject some logic into the Unity build process in order to do things like modify the manifest.
Typically, you can do this by implementing the following interfaces:
* `IPreprocessBuildWithReport`
* `IPostprocessBuildWithReport`
* `IPostGenerateGradleAndroidProject`
Features **should not** implement these classes, but should instead implement `OpenXRFeatureBuildHooks`, which only provide callbacks when the feature is enabled. For more information, see `OpenXRFeatureBuildHooks`.
### Build time validation
If your feature has project setup requirements or suggestions that require user acceptance, implement `GetValidationChecks`. Features can add to a list of validation rules which Unity evaluates at build time. If any validation rule fails, Unity displays a dialogue asking you to fix the error before proceeding. Unity can also presents warning through the same mechanism. It's important to note which build target the rules apply to.
Example:
```c#
#if UNITY_EDITOR
protected override void GetValidationChecks(List<OpenXRFeature.ValidationRule> results, BuildTargetGroup targetGroup)
{
if (targetGroup == BuildTargetGroup.WSA)
{
results.Add( new ValidationRule(this){
message = "Eye Gaze support requires the Gaze Input capability.",
error = false,
checkPredicate = () => PlayerSettings.WSA.GetCapability(PlayerSettings.WSACapability.GazeInput),
fixIt = () => PlayerSettings.WSA.SetCapability(PlayerSettings.WSACapability.GazeInput, true)
} );
}
}
#endif
```
![feature-validation](images/ProjectValidation/feature-validation.png)
### Custom Loader library
One and only one Unity OpenXR feature per BuildTarget can have a custom loader library. This must be named `openxr_loader` with native platform naming conventions (for example, `libopenxr_loader.so` on Android).
Features with a custom loader library must set the `OpenXRFeatureAttribute`: `CustomRuntimeLoaderBuildTargets` to a list of BuildTargets in which a custom loader library is expected to be used. Features that do not use a custom loader library do not have to set `CustomRuntimeLoaderBuildTargets` (or can set it to null or an empty list).
The custom loader library must be placed in the same directory or a subdirectory of the C# script that extends the `OpenXRFeature` class. When the feature is enabled, Unity will include the custom loader library in the build for the active BuildTarget, instead of the default loader library for that target.
### Feature native libraries
Any native libraries included in the same directory or a subdirectory of your feature will only be included in the built Player if your feature is enabled.
## Feature use cases
### Intercepting OpenXR function calls
To intercept OpenXR function calls, override `OpenXRFeature.HookGetInstanceProcAddr`. Returning a different function pointer allows intercepting any OpenXR method. For an example, see the `Intercept Feature` sample.
### Calling OpenXR functions from a feature
To call an OpenXR function within a feature you first need to retrieve a pointer to the function. To do this use the `OpenXRFeature.xrGetInstanceProcAddr` function pointer to request a pointer to the function you want to call. Using `OpenXRFeature.xrGetInstanceProcAddr` to retrieve the function pointer ensures that any intercepted calls set up by features using `OpenXRFeature.HookGetInstanceProcAddr` will be included.
### Providing a Unity subsystem implementation
`OpenXRFeature` provides several XR Loader callbacks where you can manage the lifecycle of Unity subsystems. For an example meshing subsystem feature, see the `Meshing Subsystem Feature` sample.
Note that a `UnitySubsystemsManifest.json` file is required in order for Unity to discover any subsystems you define. At the moment, there are several restrictions around this file:
* It must be only 1 subfolder deep in the project or package.
* The native library it refers to must be only 1-2 subfolders deeper than the `UnitySubsystemsManfiest.json` file.

View File

@@ -0,0 +1,88 @@
---
uid: openxr-composition-layers
---
# Composition Layers Support
The OpenXR Composition Layers feature provides support for rendering high quality images on layer types, such as cylinder, equirect, cube, and more, on platforms like the Quest headsets.
This functionality allows developers to manage visual layers in a flexible, performant way, tailored for XR applications.
Refer to the [Composition Layers](https://docs.unity3d.com/Packages/com.unity.xr.compositionlayers@latest) documentation for information about using composition layers in a scene.
## Installation
To use this feature, install the [Composition Layers package](https://docs.unity3d.com/Packages/com.unity.xr.compositionlayers@1.0/manual/index.html). Follow the steps in the package documentation for installation details.
## Enabling Composition Layers
Once the package is installed, you can enable OpenXR Composition Layers in your Unity project:
1. Open the **Project Settings** window (menu: **Edit > Project Settings**).
2. Select **XR Plug-in Management** from the list of settings on the left.
3. If necessary, enable **OpenXR** in the list of **Plug-in Providers**. Unity installs the OpenXR plug-in, if not already installed.
4. Select the **OpenXR** settings page under **XR Plug-in Management**.
5. Enable the **Composition Layer Support** option in the **OpenXR Feature Groups** area of the **OpenXR** settings.
![OpenXR feature options](../../images/openxr-features.png)
## Custom Layers
In addition to the built-in layer types supported by the Composition Layers feature, you can create and register your own custom composition layers. This is particularly useful when your project requires non-standard visual behavior, optimized layer rendering, or complex interactions in AR/VR environments.
### Custom Layer Example
The following example demonstrates how to create a custom layer handler for a custom layer type. This handler is responsible for managing the lifecycle of the layer, rendering, and other properties.
```c#
#if UNITY_EDITOR
[UnityEditor.XR.OpenXR.Features.OpenXRFeature(UiName = "OpenXR Custom Layer Handler Example",
BuildTargetGroups = new[] { BuildTargetGroup.Standalone, BuildTargetGroup.WSA, BuildTargetGroup.Android },
Company = "Unity",
Desc = "An example to demonstrate how to enable a handler for a customized composition layer type.",
DocumentationLink = "",
FeatureId = "com.unity.openxr.features.customlayerexample",
OpenxrExtensionStrings = "",
Version = "1")]
#endif
public class CustomFeature : OpenXRFeature
{
bool isSubscribed;
protected override void OnEnable()
{
if (OpenXRLayerProvider.isStarted)
CreateAndRegisterLayerHandler();
else
{
OpenXRLayerProvider.Started += CreateAndRegisterLayerHandler;
isSubscribed = true;
}
}
protected override void OnDisable()
{
if (isSubscribed)
{
OpenXRLayerProvider.Started -= CreateAndRegisterLayerHandler;
isSubscribed = false;
}
}
protected void CreateAndRegisterLayerHandler()
{
if (enabled)
{
var layerHandler = new CustomLayerHandler();
OpenXRLayerProvider.RegisterLayerHandler(typeof(CustomQuadLayerData), layerHandler);
}
}
}
#endif
```
This code can also be imported from the OpenXR Samples in the Package Manager.
### When to Use Custom Layers
You may want to create a custom layer in situations where:
- You need to implement a specific rendering technique not covered by the standard layer types (such as a specialized quad or cylinder layer).
- Performance optimizations for specific layer interactions are required.
- Create unique visual effects or layer behaviors in your XR application.
By registering custom layer handlers, you can gain full control over how the composition layers are processed and rendered, allowing for more tailored XR experiences.

View File

@@ -0,0 +1,28 @@
---
uid: openxr-dpad-interaction
---
# D-Pad Interaction
Unity OpenXR provides support for the Dpad Binding extension specified by Khronos. Use this layout to retrieve the bindings data that the extension returns. This extension allows the application to bind one or more digital actions to a trackpad or thumbstick as though it were a dpad by defining additional component paths to suggest bindings for.
Enables the OpenXR interaction profile for Dpad Interaction and exposes the `<DPad>` layout within the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/).
For more information about the Dpad Binding extension, refer to the [OpenXR Specification](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_dpad_binding).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
| `/input/thumbstick/dpad_up` | thumbstickDpadUp | Boolean |
| `/input/thumbstick/dpad_down` | thumbstickDpadDown | Boolean |
| `/input/thumbstick/dpad_left` | thumbstickDpadLeft | Boolean |
| `/input/thumbstick/dpad_right` | thumbstickDpadRight | Boolean |
| `/input/trackpad/dpad_up` | trackpadDpadUp | Boolean |
| `/input/trackpad/dpad_down` | trackpadDpadDown | Boolean |
| `/input/trackpad/dpad_left` | trackpadDpadLeft | Boolean |
| `/input/trackpad/dpad_right` | trackpadDpadRight | Boolean |
| `/input/trackpad/dpad_center` | trackpadDpadCenter | Boolean |

View File

@@ -0,0 +1,23 @@
---
uid: openxr-eye-gaze-interaction
---
# Eye Gaze Interaction
Unity OpenXR provides support for the Eye Tracking Interaction extension specified by Khronos. Use this layout to retrieve the pose data that the extension returns.
At present, this device does not appear in the Unity Input System drop-down menus. To bind, go the gaze position/rotation, and use the following binding paths.
|**Data**|**Binding Path**|
|--------|------------|
|Position|`<EyeGaze>/pose/position`|
|Rotation|`<EyeGaze>/pose/rotation`|
For more information about the Eye Gaze extension, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_eye_gaze_interaction).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
| `/input/gaze_ext/pose` | pose | Pose |

View File

@@ -0,0 +1,206 @@
---
uid: openxr-foveated-rendering
---
# Foveated rendering in OpenXR
Foveated rendering is an optimization technique that can speed up rendering with little perceived impact on visual quality. Foveated rendering works by lowering the resolution of areas in the user's peripheral vision. On headsets that support eye-tracking as well as foveated rendering, the higher-resolution area can be centered where the user is currently looking. Without eye-tracking, the higher resolution area is fixed near the middle of the screen. Fixed foveated rendering can be more apparent to the user since they can shift their eyes to look at the peripheral areas.
OpenXR platforms use the variable shading rate (VSR) technique for foveated rendering, which does not require you to change custom shaders. (However, if you are creating assets that should work on all XR platforms, refer to the "Foveated rendering shaders" topic in [Foveated rendering](https://docs.unity3d.com/Manual/xr-foveated-rendering.html) to learn how to write shaders and shader graphs that work under all supported foveated rendering methods.)
OpenXR devices can implement VRS using a variety of techniques and a single device can support more than one implementation. The Unity OpenXR plug-in chooses from the following techniques, in this order, depending on what the current device supports:
1. Gaze-based Fragment Density Map (GFDM) from provider.
2. Fixed Fragment Density Map (FFDM) from provider.
3. Fragment Shading Rate (FSR) using a provider's texture.
4. Fragment Shading Rate using a compute shader calculated from the asymmetric FOVs the provider gives.
This topic covers aspects of foveated rendering specific to the Unity OpenXR provider plug-in:
* [Prerequisites](#prerequisites)
* [Configure foveated rendering](#configure-foveated-rendering)
* [Use the **SRP Foveation** API](#use-the-srp-foveation-api)
* [Use the **Legacy** API](#use-the-legacy-api)
* [Request eye-tracking permission on Android](#request-eye-tracking-permission)
For general information about foveated rendering in Unity XR, refer to [Foveated rendering](https://docs.unity3d.com/Manual/xr-foveated-rendering.html).
<a id="prerequisites"></a>
## Prerequisites
To use the foveated rendering feature in OpenXR, your project must meet the following prerequisites:
* Unity 6+
* Unity OpenXR plugin (com.unity.xr.openxr) 1.11.0+
* Universal Rendering Pipeline or High Definition Render Pipeline (HDRP not recommended for mobile XR platforms such as the Meta Quest family of devices)
Alternately, you can use the Meta Core XR SDK package to access the OpenXR foveated rendering feature on Quest devices:
* Unity 2022.2+, Unity 6+
* Unity OpenXR plugin (com.unity.xr.openxr) 1.11.0+
* Meta Core XR SDK 68.0+
* Built-in or Universal Rendering Pipeline
> [!NOTE]
> The primary differences between the Unity **SRP Foveation** API and the Meta API for foveated rendering include:
>
> * They uses different APIs and code paths to enable and control foveated rendering on a device.
> * The Unity **SRP Foveation** API works on all platforms that support foveated rendering, which allows you to share code across different types of devices.
> * The Unity **SRP Foveation** API does not support the Built-in Rendering Pipeline.
> * The Meta API, which only works on Quest devices, supports Unity 2022.3 and the Built-in Render Pipeline.
> * The Meta API does not support foveated rendering when you use intermediate render targets. Intermediate rendering targets are used by post-processing, tone mapping and camera stacking, for example, and may be used by other rendering features, too.
>
> Unity recommends that you use the Unity **SRP Foveation** API where possible for better compatibility. You can still use other features from the Meta Core XR SDK in conjunction with the **SRP Foveation** API, if desired.
<a id="configure-foveated-rendering"></a>
## Configure foveated rendering
You can configure foveated rendering in a project that meets the [Prerequisites](#prerequisites):
* [Configure SRP Foveation](#configure-srp-foveation)
* [Configure Legacy foveated rendering](#configure-legacy-foveated-rendering)
* [Configure gaze-based foveated rendering](#configure-gaze-based-foveated-rendering)
Once configured in settings, you must also turn on foveated rendering at runtime. By default, the foveated rendering strength or level is set to off. You must also set a runtime flag to use gaze-based foveated rendering.
Refer to the following topics for more information:
* [Use the SRP Foveation API](#use-the-srp-foveation-api)
* [Use the Legacy API](#use-the-srp-foveation-api)
<a id="configure-srp-foveation"></a>
### Configure SRP Foveation
To enable the **SRP Foveation** API in Unity 6+:
1. Open the **Project Settings** window.
2. Under **XR Plug-in Management**, select the **OpenXR** settings.
3. Set the **Foveated Rendering API** option to **SRP Foveation**.
3. In the list of **OpenXR Feature Groups**, select **All Features**.
4. Enable the **Foveated Rendering** feature.
![SRP Foveation settings](../images/FoveatedRendering/xr-foveation-srp-api-settings.png)<br/>*Settings to enable foveated rendering with the **SRP Foveation** API*
After you have configured the settings, you must also turn on foveated rendering at runtime. Refer to [Use the SRP Foveation API](#use-the-srp-foveation-api) for more information.
> [!NOTE]
> You must configure the project to use either the [Universal Render Pipeline (URP)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@17.0/manual/InstallURPIntoAProject.html) or the [High Definition Render Pipeline (HDRP)](https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@17.0/manual/convert-project-from-built-in-render-pipeline.html), if you have not already done so.
<a id="configure-legacy-foveated-rendering"></a>
### Configure Legacy foveated rendering
In Unity 6+, set the OpenXR **Foveated Render API** option to **Legacy** to use the Meta Core XR SDK, which only supports the Meta Quest family of devices. In Unity 2022, there is no option to select a **Foveated Rendering API**. Only the legacy API using the Meta Core XR SDK is supported.
1. Install the [Meta Core XR SDK](com.unity3d.kharma:upmpackage/com.meta.xr.sdk.core) package, if necessary. You can get this package from the [Unity Asset Store](https://assetstore.unity.com/packages/tools/integration/meta-xr-core-sdk-269169). The package adds the Meta OpenXR feature group to the OpenXR along with the associated features. Refer to the [Meta Developer site](https://developer.oculus.com/downloads/package/meta-xr-core-sdk/68.0) for more information.
2. Open the **Project Settings** window.
3. Select the **XR Plug-in Management** settings from the list on the left.
4. Select the **Android** tab.
5. Under **OpenXR**, enable the **Meta XR feature group**, which is added when you install the Meta Core SDK package. (You might be prompted to restart the Unity Editor, which you can do now or after you finish configure these settings.)
![Enable Meta XR feature group](../images/FoveatedRendering/xr-meta-feature-group.png)
6. Select the **OpenXR** settings area (below **XR Plug-in Management**).
7. Set the **Foveated Rendering API** option to **Legacy**.
8. In the list of **OpenXR Feature Groups**, select **All Features**.
9. Disable the **Foveated Rendering** feature, if it is enabled.
10. Enable the **Meta XR Foveated Rendering** feature.
11. (Optional) Enable the **Meta XR Eye Tracked Foveation** feature.
![Legacy Foveation settings](../images/FoveatedRendering/xr-foveation-legacy-settings.png)<br/>*Settings to enable foveated rendering with the **Legacy** API*
After you have configured the settings, you must also turn on foveated rendering at runtime. Refer to [Use the Legacy API](#use-the-legacy-api) for more information.
> [!NOTE]
> The Meta Core XR SDK is a third-party package, which is not under Unity control. The OpenXR features and API it provides can change without notice.
<a id="configure-gaze-based-foveated-rendering"></a>
### Configure gaze-based foveated rendering
Devices that provide eye tracking can support gaze-based foveated rendering in which the highest resolution area is centered where the user is looking.
When using the Unity **SRP Foveation** API, you do not need to enable gaze-based foveated rendering in the OpenXR settings. You do need to [turn the feature on at runtime](#use-the-srp-foveation-api) and make sure any required permissions are enabled.
When using the **Legacy**, Meta Core XR SDK, you must enable the **Meta XR Eye Tracked Foveation** OpenXR feature.
To use eye-tracking data, you must [Request eye-tracking permission on Android](#request-eye-tracking-permission). Other platforms may have similar requirements.
<a id="use-the-srp-foveation-api"></a>
## Use the SRP Foveation API
After you have configured foveated rendering in the OpenXR settings, you must also turn the feature on at runtime. If you want to use gaze-based foveated rendering, you must set a runtime flag, which might require user permission.
To specify the amount, or *strength*, of the foveation effect, you must assign a value between 0 and 1 to the [XRDisplaySubsystem.foveatedRenderingLevel](xref:UnityEngine.XR.XRDisplaySubsystem.foveatedRenderingLevel) property. The default value of zero turns foveation off altogether. A value of one is the maximum strength. Different device types can interprete this value in the way that best suits their native API. Meta Quest devices, for example, have discrete levels for setting the foveation strength: if you assign a value of `0.5` to `foveatedRenderingLevel`, the provider plug-in sets the device's *medium* foveation level.
To specify that you want to use gaze-based foveated rendering, set [XRDisplaySubsystem.foveatedRenderingFlags](xref:UnityEngine.XR.XRDisplaySubsystem.foveatedRenderingFlags) to [FoveatedRenderingFlags.GazeAllowed](xref:UnityEngine.XR.XRDisplaySubsystem.FoveatedRenderingFlags.GazeAllowed). If you do not set this flag, the device doesn't support gaze-based foveated rendering, or the user turns off or denies permission to use eye-tracking, then fixed foveated rendering is performed.
To set either of these foveated rendering APIs, you must first get a reference to the active [XRDisplaySubsystem](xref:UnityEngine.XR.XRDisplaySubsystem) from the Unity [SubsystemManager](xref:UnityEngine.SubsystemManager). Unity supports multiple subsystems of the same type, and returns a list when you get the subsystems of a given type. Ordinarily, only one `XRDisplaySubsystem` exists and you can use the lone subsystem in the `XRDisplaySubsystem` list returned by [SubsystemManager.GetSubsystems](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/SubsystemManager.GetSubsystems.html).
The following code example illustrates how to set foveated rendering to full strength and enable gaze-based foveation after getting the instance of the active `XRDisplaySubsystem`:
```C#
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.XR;
public class FoveationStarter : MonoBehaviour
{
List<XRDisplaySubsystem> xrDisplays = new List<XRDisplaySubsystem>();
void Start()
{
SubsystemManager.GetSubsystems(xrDisplays);
if (xrDisplays.Count == 1)
{
xrDisplays[0].foveatedRenderingLevel = 1.0f; // Full strength
xrDisplays[0].foveatedRenderingFlags
= XRDisplaySubsystem.FoveatedRenderingFlags.GazeAllowed;
}
}
}
```
> [!NOTE]
> This code example relies on methods available in Unity 6+. It does not compile in earlier versions.
<a id="use-the-legacy-api"></a>
## Use the Legacy API
This API was built only for Quest headsets; it may not be supported on other devices. You must install Meta's Core XR SDK package for this API to be available.
After you configured foveated rendering in the OpenXR settings, you must also turn the feature on at runtime. If you want to use gaze-based foveated rendering, you must set a runtime flag, which might require user permission.
The following code example illustrates how to set foveated rendering to High and enable gaze-based foveation using the **Legacy API** and the Meta Core XR SDK package:
```C#
using UnityEngine;
using UnityEngine.XR;
public class FoveationStarter : MonoBehaviour
{
private void Start()
{
OVRManager.foveatedRenderingLevel = OVRManager.FoveatedRenderingLevel.High;
OVRManager.eyeTrackedFoveatedRenderingEnabled = true;
}
}
```
Refer to Meta's [OVRManager Class Reference](https://developer.oculus.com/reference/unity/v67/class_o_v_r_manager#acbd6d504192d2a2a7461382a4eae0715a84ec48f67b50df5ba7f823879769e0ad) for more information.
<a id="request-eye-tracking-permission"></a>
## Request eye-tracking permission on Android
The Android platform requires the user to grant permission before your app can access eye-tracking data. Eye-tracking permission is required to use gaze-based foveated rendering.
To declare that your application uses eye tracking, you must add a `uses-feature` and a `uses-permission` element to your application's Android manifest file:
``` xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools">
<uses-feature android:name="oculus.software.eye_tracking" android:required="false" />
<uses-permission android:name="com.oculus.permission.EYE_TRACKING" />
... the rest of the manifest elements ...
```
Refer to [Declare permissions for an application](xref:um-android-permissions-declare) for instructions about how to add these and other custom elements to the Android manifest.
If the user denies permission, your application uses fixed foveated rendering instead. Refer to [Request runtime permissions
](xref:um-android-requesting-permissions) for more information about handling Android permissions issues, including how to handle cases where the user has denied permission.

View File

@@ -0,0 +1,24 @@
---
uid: openxr-hand-common-poses-interaction
---
# Hand Common Poses Interaction
Unity OpenXR provides support for the Hand Interaction extension specified by Khronos. Use this layout to retrieve the bindings data that the extension returns. This extension defines four commonly used action poses for all user hand
interaction profiles including both hand tracking devices and motion controller devices.
Enables the OpenXR interaction feature for Hand Common Poses Interaction and exposes the `<HandInteractionPoses>` layout within the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/).
OpenXR Specification about Hand Interaction Extension will be updated here when it is available.
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/input/pinch_ext/pose` | pinchPose | Pose |
|`/input/poke_ext/pose` | pokePose | Pose |

View File

@@ -0,0 +1,32 @@
---
uid: openxr-hand-interaction-profile
---
# Hand Interaction Profile
The hand interaction profile is designed for runtimes which provide hand inputs using hand tracking devices instead of controllers with triggers or buttons.
The hand interaction profile allows hand tracking devices to provide commonly used gestures and action poses. Enable this OpenXR interaction profile to expose the `<HandInteraction>` device layout within the [Unity Input System](xref:input-system-index).
OpenXR Specification about Hand Interaction Profile will be updated here when it is available.
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/input/pinch_ext/pose` | pinchPose | Pose |
|`/input/poke_ext/pose` | pokePose | Pose |
|`/input/pinch_ext/value`| pinchValue | Float |
|`/input/pinch_ext/ready_ext` | pinchReady | Boolean|
|`/input/aim_activate_ext/value`| pointerActivateValue | Float |
|`/input/aim_activate_ext/ready_ext` | pointerActivateReady | Boolean|
|`/input/grasp_ext/value`| graspValue | Float |
|`/input/grasp_ext/ready_ext` | graspReady | Boolean|
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,35 @@
---
uid: openxr-hp-reverb-g2-controller-profile
---
# HP Reverb G2 Controller Profile
Enables the OpenXR interaction profile for the HP Reverb G2 Controller and exposes the `<ReverbG2Controller>` device layout within the [Unity Input System](xref:input-system-index).
For more information about the HP Reverb G2 interaction profile, refer to the [OpenXR Specification](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_hp_mixed_reality_controller).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/x/click`| primaryButton (Left Hand Only) | Boolean |
|`/input/y/click`| secondaryButton (Left Hand Only) | Boolean |
|`/input/a/click`| primaryButton (Right Hand Only) | Boolean |
|`/input/b/click`| secondaryButton (Right Hand Only) | Boolean |
|`/input/menu/click` | menu | Boolean|
|`/input/squeeze/value`| grip | Float |
|`/input/squeeze/value`| gripPressed | Boolean (float cast to Boolean) |
|`/input/trigger/value`|trigger| Float |
|`/input/trigger/value`| triggerPressed | Boolean (float cast to Boolean) |
|`/input/thumbstick`| thumbstick | Vector2 |
|`/input/thumbstick/click`| thumbstickClicked | Boolean |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,33 @@
---
uid: openxr-htc-vive-controller-profile
---
# HTC Vive Controller Profile
Enables the OpenXR interaction profile for the HTC Vive Controller and exposes the `<ViveController>` device layout within the [Unity Input System](xref:input-system-index).
For more information about the HTC Vive interaction profile, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_htc_vive_controller_profile).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/system/click`| select | Boolean |
|`/input/squeeze/click`| grip | Float ( Boolean value cast to float)|
|`/input/squeeze/click`| gripButton | Boolean |
|`/input/menu/click` | menu | Boolean|
|`/input/trigger/value`|trigger| Float |
|`/input/trigger/click`|triggerPressed| Boolean |
|`/input/trackpad`|trackpad| Vector2 |
|`/input/trackpad/click`|trackpadClicked| Boolean |
|`/input/trackpad/touch`|trackpadTouched| Boolean |
|`/input/grip/pose`| devicePose| Pose |
|`/input/aim/pose`|pointer| Pose |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,28 @@
---
uid: openxr-khronos-simple-controller-profile
---
# Khronos Simple Controller Profile
Enables the OpenXR interaction profile for the Khronos Simple Controller and exposes the `<SimpleController>` device layout within the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/).
For more information about the Khronos Simple Controller interaction profile, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_khronos_simple_controller_profile).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/select/click`| select | Boolean |
|`/input/menu/click` | menu | Boolean |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
| Unity Layout Only | pointerPosition | Vector3 |
| Unity Layout Only | pointerRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,100 @@
---
uid: openxr-meta-quest-support
---
# Meta Quest Support
Understand how to configure the OpenXR plug-in for Meta Quest devices.
The Meta Quest Support feature enables Meta Quest support for the OpenXR plug-in. The **Meta Quest Support** window provides configurable settings specific for Meta Quest devices.
Refer to the following sections to understand how to [Enable Meta Quest Support](#Enable-support), and the [Settings](#settings) you can configure.
## Enable Meta Quest Support {#enable}
To deploy to Meta Quest, enable the Meta Quest Support feature on the Android build target as follows:
1. Open the Project Settings window (menu: **Edit > Project Settings**).
2. Select the **XR Plug-in Management** from the list of settings on the left.
3. If necessary, enable **OpenXR** in the list of **Plug-in Providers**. Unity installs the OpenXR plug-in, if not already installed.
4. Select the OpenXR settings page under XR Plug-in Management.
5. Add the **Oculus Touch Controller Profile** to the **Interaction Profiles** list. (You can have multiple profiles enabled in the list, the OpenXR chooses the one to use based on the current device at runtime.)
6. Enable **Meta Quest Support** under **OpenXR Feature Groups**.
When you enable Meta Quest Support, Unity produces Application Package Kit (APK) files that you can run on the Quest family of devices.
## Open the Meta Quest Support window
The **Meta Quest Support** settings window provides the settings you can configure for OpenXR support on Meta Quest devices.
To open the **Meta Quest Support** window:
1. Open the **OpenXR** section of **XR Plug-in Management** (menu: **Edit** > **Project Settings** > **XR Plug-in Management** > **OpenXR**).
2. Under **OpenXR Feature Groups**, enable **Meta Quest Support**.
3. Click the gear icon next to **Meta Quest Support** to open **Meta Quest Support** settings.
![Meta Quest Support in the OpenXR settings.](../images/meta-quest-support.png)<br/>*Meta Quest Support feature.*
## Settings reference {#settings}
The following sections provide a reference of the settings you can configure in the **Meta Quest Support** window.
### Rendering Settings
Use the following settings to configure rendering in your project.
#### Symmetric Projection (Vulkan)
If enabled, when the application begins it will create a stereo symmetric view that changes the eye buffer resolution based on the Inter-Pupillary Distance (IPD). Provides a performance benefit across all IPD values.
#### Optimize Buffer Discards (Vulkan)
Enable this setting to enable an optimization that allows 4x Multi Sample Anti Aliasing (MSAA) textures to be memoryless on Vulkan.
#### Optimize Multiview Render Regions (Vulkan)
Enable to activate Multiview Render Regions optimizations at application start (Unity 6.1 and newer).
To learn more about this feature, refer to [Multiview Render Regions](xref:openxr-multiview-render-regions).
#### Space Warp motion vector texture format
Choose the format used by the motion vector texture to store its values. The option you choose depends on whether you want to prioritize visual quality and performance.
The options you can choose are:
| Option | Description |
| :---------- | :---------- |
| **RGBA16f** | Use this for more precise values. This can improve the visual quality of Space Warp. |
| **RG16f** | Use this option for reduced memory usage, but slightly less precision. |
To learn more about Space Warp, refer to [URP Application Spacewarp](xref:um-xr-application-spacewarp).
### Manifest Settings
Use the following settings to configure your project manifest.
#### Force Remove Internet Permission
Enable to force the removal of internet permissions added to the [Android App Manifest](xref:um-android-manifest).
#### System Splash Screen
Uses a `PNG` in the `Assets` folder as the system splash screen image. If set, the OS will display the system splash screen as a high quality compositor layer as soon as the app is starting to launch, until the app submits the first frame.
Use the picker (&#8857;) to select an image from the `Assets` folder you want to use as the system splash screen image.
### Target Devices
Select the Quest devices your project targets.
### Experimental
The **Experimental** section contains experimental settings that are under active development.
> [!NOTE]
> Experimental settings might change before theyre verified.
## Additional resources
* [Develop for Meta Quest](xref:um-xr-meta-quest-develop) (Unity manual)
* [Oculus All In on OpenXR: Deprecates Proprietary APIs](https://developer.oculus.com/blog/oculus-all-in-on-openxr-deprecates-proprietary-apis) (Meta developer blog)

View File

@@ -0,0 +1,46 @@
---
uid: openxr-meta-quest-plus-touch-controller-profile
---
# Meta Quest Touch Plus Controller Profile
Enables the OpenXR interaction profile for Meta Quest Touch Plus controllers and exposes the `<QuestTouchPlusController>` device layout within the [Unity Input System](xref:input-system-index).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/thumbstick`| thumbstick | Vector2 |
|`/input/squeeze/value`| grip | Float |
|`/input/squeeze/value`| gripPressed | Boolean (float cast to Boolean) |
|`/input/menu/click`| menu (Left Hand Only)| Boolean |
|`/input/system/click`| menu (Right Hand Only)| Boolean |
|`/input/a/click`| primaryButton (Right Hand Only) | Boolean |
|`/input/a/touch`| primaryTouched (Right Hand Only) | Boolean |
|`/input/b/click`| secondaryButton (Right Hand Only) | Boolean |
|`/input/b/touch`| secondaryTouched (Right Hand Only) | Boolean |
|`/input/x/click`| primaryButton (Left Hand Only) | Boolean |
|`/input/x/touch`| primaryTouched (Left Hand Only) | Boolean |
|`/input/y/click`| secondaryButton (Left Hand Only) | Boolean |
|`/input/y/touch`| secondaryTouched (Left Hand Only) | Boolean |
|`/input/trigger/value`| trigger | Float |
|`/input/trigger/value`| triggerPressed | Boolean (float cast to Boolean) |
|`/input/trigger/touch`| triggerTouched| Boolean (float cast to Boolean) |
|`/input/thumbstick/click`| thumbstickClicked | Boolean |
|`/input/thumbstick/touch`| thumbstickTouched | Boolean |
|`/input/thumbrest/touch`| thumbrestTouched | Boolean |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/input/trigger/force` | triggerForce | Float |
|`/input/trigger/curl_meta` | triggerCurl | Float |
|`/input/trigger/slide_meta` | triggerSlide | Float |
|`/input/trigger/proximity_meta` | triggerProximity | Boolean |
|`/input/thumb_meta/proximity_meta` | thumbProximity | Boolean |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,48 @@
---
uid: openxr-meta-quest-pro-touch-controller-profile
---
# Meta Quest Pro Touch Controller Profile
Enables the OpenXR interaction profile for Meta Quest Pro controllers and exposes the `<QuestProTouchController>` device layout within the [Unity Input System](xref:input-system-index).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/thumbstick`| thumbstick | Vector2 |
|`/input/squeeze/value`| grip | Float |
|`/input/squeeze/value`| gripPressed | Boolean (float cast to Boolean) |
|`/input/menu/click`| menu (Left Hand Only)| Boolean |
|`/input/system/click`| menu (Right Hand Only)| Boolean |
|`/input/a/click`| primaryButton (Right Hand Only) | Boolean |
|`/input/a/touch`| primaryTouched (Right Hand Only) | Boolean |
|`/input/b/click`| secondaryButton (Right Hand Only) | Boolean |
|`/input/b/touch`| secondaryTouched (Right Hand Only) | Boolean |
|`/input/x/click`| primaryButton (Left Hand Only) | Boolean |
|`/input/x/touch`| primaryTouched (Left Hand Only) | Boolean |
|`/input/y/click`| secondaryButton (Left Hand Only) | Boolean |
|`/input/y/touch`| secondaryTouched (Left Hand Only) | Boolean |
|`/input/trigger/value`| trigger | Float |
|`/input/trigger/value`| triggerPressed | Boolean (float cast to Boolean) |
|`/input/trigger/touch`| triggerTouched| Boolean (float cast to Boolean) |
|`/input/thumbstick/click`| thumbstickClicked | Boolean |
|`/input/thumbstick/touch`| thumbstickTouched | Boolean |
|`/input/thumbrest/touch`| thumbrestTouched | Boolean |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/input/stylus_fb/force` | stylusForce | Float |
|`/input/trigger/curl_fb` | triggerCurl | Float |
|`/input/trigger/slide_fb` | triggerSlide | Float |
|`/input/trigger/proximity_fb` | triggerProximity | Boolean |
|`/input/thumb_fb/proximity_fb` | thumbProximity | Boolean |
|`/output/haptic` | haptic | Vibrate |
|`/output/trigger_haptic_fb` | hapticTrigger | Vibrate |
|`/output/thumb_haptic_fb` | hapticThumb | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,29 @@
---
uid: openxr-microsoft-hand-interaction
---
# Microsoft Hand Interaction
Unity OpenXR provides support for the Hololens 2 Hand interaction profile. This layout inherits from `<XRController>` so bindings that use XR Controller and are available on this device (for example, `<XRController>/devicePosition`) will bind correctly.
This interaction profile does not provide hand mesh or hand rig data. These will be added in the future.
For more information about the Microsoft Hand Interaction extension, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_MSFT_hand_interaction).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/select/click`| select | Boolean |
|`/input/squeeze/value` | squeeze | Float |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
| Unity Layout Only | pointerPosition | Vector3 |
| Unity Layout Only | pointerRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,36 @@
---
uid: openxr-microsoft-mixed-reality-motion-controller-profile
---
# Microsoft Mixed Reality Motion Controller Profile
Enables the OpenXR interaction profile for the Microsoft Mixed Reality Motion controller and exposes the `<WMRSpatialController>` device layout within the [Unity Input System](xref:input-system-index).
For more information about the Microsoft Mixed Reality Motion Controller interaction profile, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_microsoft_mixed_reality_motion_controller_profile).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/thumbstick`| joystick | Vector2 |
|`/input/trackpad`| touchpad | Vector2 |
|`/input/squeeze/click`| grip | Float (Boolean cast to float) |
|`/input/squeeze/click`| gripPressed | Boolean |
|`/input/menu/click`| menu | Boolean |
|`/input/trigger/value`| trigger | Float |
|`/input/trigger/value`| triggerPressed | Boolean (float cast to Boolean) |
|`/input/thumbstick/click`| joystickClicked | Boolean |
|`/input/trackpad/click`| touchpadClicked | Boolean |
|`/input/trackpad/touch`| touchpadTouched | Boolean |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
| Unity Layout Only | pointerPosition | Vector3 |
| Unity Layout Only | pointerRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,25 @@
---
uid: openxr-multiview-render-regions
---
# Multiview Render Regions
The Multiview Render Regions feature is an optimization technique that prevents processing on areas of the screen that are not visible to the user.
For a detailed explanation of Multiview Render Regions, refer to [Multiview Render Regions](https://docs.unity3d.com/6000.1/Documentation/Manual/xr-multiview-render-regions.html) in the Unity Manual.
## Prerequisites
To enable this feature, you will need the following:
* Unity 6.1 or newer.
* Ensure that the Vulkan API is enabled. This feature is not available on other graphics APIs at this point in time.
## Enable Multiview Render Regions
To enable the Multiview Render Regions feature:
1. Open the **OpenXR** section of **XR Plug-in Management** (menu: **Edit** > **Project Settings** > **XR Plug-in Management** > **OpenXR**).
2. Under **All Features**, enable **Meta Quest Support**.
3. Use the **Gear** icon to open **Meta Quest Support** settings.
4. Under **Rendering Settings**, enable **Optimize Multiview Render Regions**.
![The Optimize Multiview Render Regions feature is enabled in the OpenXR Rendering Settings.](../images/multiview-render-regions.png)<br/>*Enable the Optimize Multiview Render Regions feature in Rendering Settings.*

View File

@@ -0,0 +1,42 @@
---
uid: openxr-oculus-touch-controller-profile
---
# Oculus Touch Controller Profile
Enables the OpenXR interaction profile for Oculus Touch controllers and exposes the `<OculusTouchController>` device layout within the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/).
For more information about the Oculus Touch interaction profile, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_oculus_touch_controller_profile).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/thumbstick`| thumbstick | Vector2 |
|`/input/squeeze/value`| grip | Float |
|`/input/squeeze/value`| gripPressed | Boolean (float cast to Boolean) |
|`/input/menu/click`| menu (Left Hand Only)| Boolean |
|`/input/system/click`| menu (Right Hand Only)| Boolean |
|`/input/a/click`| primaryButton (Right Hand Only) | Boolean |
|`/input/a/touch`| primaryTouched (Right Hand Only) | Boolean |
|`/input/b/click`| secondaryButton (Right Hand Only) | Boolean |
|`/input/b/touch`| secondaryTouched (Right Hand Only) | Boolean |
|`/input/x/click`| primaryButton (Left Hand Only) | Boolean |
|`/input/x/touch`| primaryTouched (Left Hand Only) | Boolean |
|`/input/y/click`| secondaryButton (Left Hand Only) | Boolean |
|`/input/y/touch`| secondaryTouched (Left Hand Only) | Boolean |
|`/input/trigger/value`| trigger | Float |
|`/input/trigger/value`| triggerPressed | Boolean (float cast to Boolean) |
|`/input/trigger/touch`| triggerTouched| Boolean (float cast to Boolean) |
|`/input/thumbstick/click`| thumbstickClicked | Boolean |
|`/input/thumbstick/touch`| thumbstickTouched | Boolean |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,18 @@
---
uid: openxr-palm-pose-interaction
---
# Palm Pose Interaction
Unity OpenXR provides support for the Palm Pose extension specified by Khronos. Use this layout to retrieve the pose data that the extension returns. This extension also adds a new input component path using this "palm_ext" pose identifier to existing interaction profiles when active.
Enables the OpenXR interaction feature for Palm Pose Interaction and exposes the `<PalmPose>` layout within the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/).
For more information about the Palm Pose extension, refer to the [OpenXR Specification](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_palm_pose).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
| `/input/palm_ext/pose` | palmPose | Pose |

View File

@@ -0,0 +1,182 @@
---
uid: openxr-performance-settings
---
# XR performance settings
The OpenXR performance settings feature lets you provide performance hints to an OpenXR runtime and allows you to get notification when an important aspect of device performance changes.
XR devices must balance power and thermal state against performance to achieve an optimal user experience. You can provide performance hints to an OpenXR runtime to help it make the best tradeoffs for the task your application is running. For example, if your application is displaying a scene consisting of a loading graphic or simple menu without significant rendering requirements, you could tell the runtime to operate at a lower power level to save energy and thermal capacity for a later, more complex scene. Likewise, if you have a sequence that is very demanding, you could tell the runtime to operate at max capacity for a short time. You can provide hints separately for the CPU and the GPU. Refer to [Performance level hints](#performance-settings-level-hints) for more information.
You can subscribe to notifications that report changes in important aspects of device performance. These aspects include compositing, rendering, and thermal capacity. The performance notifications inform you when one of these performance categories changes between the normal, warning, and impaired states. The OpenXR runtime reports performance changes separately for the CPU and GPU. Your application can respond to these notifications by reducing the application workload. Refer to [Performance notifications](#performance-settings-notifications) for more information.
Refer to [Enable the performance settings OpenXR feature](#enable-performance-feature) for instructions about enabling the feature in your project.
> [!NOTE]
> The target XR platform must support the OpenXR "XR\_EXT\_performance\_settings" extension. Otherwise, the XR Performance Settings won't be activated at runtime. Be sure to confirm that your target platform supports the extension.
For more information about the OpenXR Performance Settings extension, refer to the [OpenXR Specification](https://registry.khronos.org/OpenXR/specs/1.0/html/xrspec.html#XR_EXT_performance_settings).
<a name="enable-performance-feature"></a>
## Enable the performance settings OpenXR feature
To use the performance settings API, you must enable it in the **OpenXR Project Settings**:
1. Open the **Project Settings** window (menu: **Edit > Project Settings**).
2. Expand the **XR Plug-in Management** section, if necessary.
3. Select the **OpenXR** area under **XR Plug-in Management**.
4. Choose the **Platform Build Target** from the tabs along the top of the **OpenXR** settings page.
5. Check the box next to **XR Performance Settings** (in the **All Features** group) to enable the feature.
6. Repeat for other platforms, if desired.
![](../images/performance-settings-feature.png)
<a name="performance-settings-level-hints"></a>
## Performance level hints
The performance level hints help an OpenXR runtime balance the tradeoffs it must make between energy usage, thermal state, and your application's performance needs. You can provide separate hints for the CPU and GPU hardware domains.
You can set the following levels as hints about your application's current performance needs:
- **Power Savings**: At this level, the OpenXR runtime prioritizes energy conservation over consistent frame rendering and latency.
- **Sustained Low**: At this level, the OpenXR runtime tries to balance resource usage and high performance, prioritizing the former. Energy savings are prioritized over low latency, but the runtime tries to maintain a relatively stable frame rendering and XR compositing flow, as long as it's thermally sustainable.
- **Sustained High**: This level is the default hint, if none is set by your application. At this level, the OpenXR runtime prioritizes consistent rendering, XR compositing and latency in a thermal range that is sustainable.
- **Boost**: At this level, the OpenXR runtime allows maximum resource usage without trying to keep the device operating in a thermally sustainable range. If the device hardware exceeds its thermal limits, the runtime must throttle performance, so you should limit use of this performance level to short durations (less that 30 seconds).
> [!NOTE]
> When setting the Performance Level Hint to **Sustained Low** or **Sustained High** levels, your application can still experience performance throttling. For example, a device might exceed thermal limits due to external circumstances, such as operating in a high-temperature environment or for an extended amount of time. You can use [Performance Notifications](#performance-settings-notifications) to detect such impending performance issues and lower application workload before the runtime must impose throttling.
Use the static method, [XrPerformanceSettingsFeature.SetPerformanceLevelHint](xref:UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings.XrPerformanceSettingsFeature.SetPerformanceLevelHint*) to set a given performance level hint for a specific CPU or GPU performance domain.
By choosing the lowest level that gives your application good performance, you can extend the device's battery life and avoid overheating. For example, you could set the **Power Savings** hint during loading screens. For normal operation, you could set **Sustained Low** for less demanding sequences, and **Sustained High** for more complex scenes. When appropriate, you could set the **Boost** hint to achieve maximum performance for a brief time.
Here are some examples of how you might use performance level hints in different scenarios:
- The application shows static pictures without any interactive elements:
```c#
XrPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain.CPU, PerformanceLevelHint.PowerSavings);
XrPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain.GPU, PerformanceLevelHint.PowerSavings);
// Show a picture sequence and continue with app loading
```
- The application is in a normal state, with simple interactivity and low complexity scenes:
```c#
XrPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain.CPU, PerformanceLevelHint.SustainedLow);
XrPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain.GPU, PerformanceLevelHint.SustainedLow);
// Run regular app process
```
- The application needs to render a complex scene with multiple, interactive composition layers:
```c#
XrPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain.GPU, PerformanceLevelHint.SustainedHigh);
// Load and process action scene
```
- The application needs to process a large amount of data on device:
```c#
XrPerformanceSettingsFeature.SetPerformanceLevelHint(PerformanceDomain.CPU, PerformanceLevelHint.Boost);
// Run complex logic
```
<a name="performance-settings-notifications"></a>
## Performance notifications
The OpenXR runtime can inform your application about performance changes, so you can react and adjust the current workload, if desired.
Performance is categorized as one of the following performance states:
- **Normal**: No performance degradation is expected and the app can run as usual.
- **Warning**: The OpenXR runtime is expecting performance degradation if device conditions do not improve.
- **Impaired**: The device is suffering performance degradation.
An OpenXR runtime monitors performance of the device CPU and GPU across a set of key performance areas, called subdomains. These subdomains include:
* [Compositing](#compositing-subdomain): A runtime task that takes all rendered layers and combines them for display.
* [Rendering](#rendering-subdomain): Your application's timely submission of frames to the compositor.
* [Thermal](#thermal-subdomain): The hardware device's temperature compared to its thermal limits.
If the performance state of a subdomain changes, the [XrPerformanceSettingsFeature](xref:UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings.XrPerformanceSettingsFeature.OnXrPerformanceChangeNotification) object dispatches an event that describes the change. Refer to [Subscribe to performance notifications](#subscribe) for information about handling this event.
When the performance state of a domain and subdomain changes for the worse, you should take mitigation measures that reduce application workload in that area. If you do not, the OpenXR runtime might impose its own, more drastic, measures.
After a sufficient period (determined by the runtime) of improved performance, a performance state can change from impaired to warning, and from warning to normal. Leaving the impaired state means that the runtime has stopped its own mitigation measures.
> [!TIP]
> Performance impairment may not be caused directly by your application, but by situational causes, such as high room temperature or a large amount of background tasks running on the device. Even so, the better you can tune your app to avoid performance degradation, the better the user experience will be across variable operating conditions.
<a name="compositing-subdomain"></a>
### Compositing subdomain
Compositing is a task performed by the OpenXR runtime to combine submitted frames for final display. The runtime must share CPU and GPU resources with your application while performing this task. If the runtime can't complete compositing in time, visual artifacts can occur. When in the impaired state, the OpenXR runtime might take actions that interfere with your application, such as limiting frame rate, ignoring submitted layers, or even shutting down the application.
* In the **Normal** state, the compositor can consistently finish with sufficient margin.
* In the **Warning** state, the compositor is finishing its task in time, but the margin is considered insufficient.
* In the **Impaired** state, the compositor cannot finish its task in time.
<a name="rendering-subdomain"></a>
### Rendering subdomain
Your application's rendering pipeline must submit rendered layers to the compositor for display. If frames aren't submitted in time for the compositor to use them, dropped frames and other artifacts can occur. In the impaired state, the OpenXR runtime might take actions that interfere with your application, such as telling the user that the application is unresponsive or displaying a tracking environment to maintain user orientation.
* In the **Normal** state, your application is consistently submitting rendered frames to the compositor in time to be used.
* In the **Warning** state, at least one layer is regularly submitted past the compositor deadline.
* In the **Impaired** state, late submission of frames has reached a critical threshold.
<a name="thermal-subdomain"></a>
### Thermal subdomain
XR devices must stay within a safe operating temperature. When a device reaches its thermal limits, the OpenXR runtime must take drastic measures to lower heat generation. These mitigations can severely impact the user experience.
* In the **Normal** state, the device is operating within a sustainable thermal range.
* In the **Warning** state, the OpenXR runtime anticipates that the device will soon overheat under the current load.
* In the **Impaired** state, the OpenXR is taking measures such as throttling performance, to reduce the device temperature.
<a name="subscribe"></a>
### Subscribe to performance notifications
Subscribe to the [XrPerformanceSettingsFeature.OnXrPerformanceChangeNotification](xref:UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings.XrPerformanceSettingsFeature.OnXrPerformanceChangeNotification) event to receive an event when the performance state of a domain and subdomain changes.
A notification event provides the following data (as a [PerformanceChangeNotification](xref:UnityEngine.XR.OpenXR.Features.Extensions.PerformanceSettings.PerformanceChangeNotification) struct):
* Old performance state (normal, warning, or impaired)
* New performance state (normal, warning, or impaired)
* Affected domain (CPU or GPU)
* Affected subdomain (compositing, rendering, or thermal)
The following code snippet illustrates how you can subscribe to the performance notification event and handle performance changes (by calling your own application-defined functions that modify performance):
```c#
// Subscribe to the performance notification event at runtime
XrPerformanceSettingsFeature.OnXrPerformanceChangeNotification += OnPerformanceChangeNotification;
// Process the notification when it happens
void OnPerformanceChangeNotification(PerformanceChangeNotification notification)
{
switch (notification.toLevel)
{
case PerformanceNotificationLevel.Normal:
// Let the application run as normal execution
RestorePerformance(notification.domain, notification.subDomain);
break;
case PerformanceNotificationLevel.Warning:
// Reduce workload of low priority tasks
LimitPerformance(notification.domain, notification.subDomain);
break;
case PerformanceNotificationLevel.Impaired:
// Execute app with the minimum required processes for the given domain and subdomain
ReducePerformance(notification.domain, notification.subDomain);
break;
}
}
```

View File

@@ -0,0 +1,2 @@
> [!NOTE]
> Some Unity controls don't correspond to an OpenXR path. Unity expresses [Pose](https://docs.unity3d.com/Documentation/ScriptReference/Pose.html) data as individual elements, whereas OpenXR expresses poses as a group of data. These additional controls contain `Unity Layout Only` in the **OpenXR Path** column. You can use this additional Pose data for more fine-grained controls. To learn more, refer to [Pose data](xref:openxr-input#pose-data).

View File

@@ -0,0 +1,44 @@
---
uid: openxr-valve-index-controller-profile
---
# Valve Index Controller Profile
Enables the OpenXR interaction profile for the Valve Index controller and exposes the `<ValveIndexController>` device layout within the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/).
For more information about the Valve Index interaction profile, refer to the [OpenXR Specification](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#_htc_vive_controller_profile).
## Available controls
The following table outlines the mapping between the OpenXR paths and Unity's implementation:
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/system/click`| system | Boolean |
|`/input/system/touch`| systemTouched | Boolean |
|`/input/a/click`| primaryButton | Boolean |
|`/input/a/touch`| primaryTouched | Boolean |
|`/input/b/click`| secondaryButton | Boolean |
|`/input/b/touch`| secondaryTouched | Boolean |
|`/input/squeeze/value`| grip | Float |
|`/input/squeeze/value`| gripPressed | Boolean (cast from float) |
|`/input/squeeze/force`| gripForce | Float |
|`/input/trigger/click`| triggerPressed | Boolean |
|`/input/trigger/value`| trigger | Float |
|`/input/trigger/touch`| triggerTouched | Boolean |
|`/input/thumbstick`| thumbstick | Vector2 |
|`/input/thumbstick/click`| thumbstickClicked | Boolean |
|`/input/thumbstick/touch`| thumbstickTouched | Boolean |
|`/input/trackpad`| trackpad | Vector2 |
|`/input/trackpad/touch`| trackpadTouched | Boolean |
|`/input/trackpad/force`| trackpadForce | Float |
|`/input/grip/pose` | devicePose | Pose |
|`/input/aim/pose` | pointer | Pose |
|`/output/haptic` | haptic | Vibrate |
| Unity Layout Only | isTracked | Flag Data |
| Unity Layout Only | trackingState | Flag Data |
| Unity Layout Only | devicePosition | Vector3 |
| Unity Layout Only | deviceRotation | Quaternion |
| Unity Layout Only | pointerPosition | Vector3 |
| Unity Layout Only | pointerRotation | Quaternion |
[!include[](snippets/unity-layout.md)]

View File

@@ -0,0 +1,5 @@
apiRules:
- exclude:
uidRegex: ^UnityEngine\.XR\.OpenXR\.Samples\..*$
- exclude:
uidRegex: ^UnityEditor\.XR\.OpenXR\.Samples\..*$

BIN
Packages/com.unity.xr.openxr/Documentation~/images/gear.png (Stored with Git LFS) Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,210 @@
---
uid: openxr-manual
---
# OpenXR Plugin
OpenXR is an open, royalty-free standard developed by Khronos that aims to simplify AR/VR development by allowing developers to seamlessly target a wide range of AR/VR devices.
## Requirements
This version of OpenXR is compatible with the following versions of the Unity Editor:
* 2021.3 LTS+
## Runtimes
Unity's OpenXR plug-in should work with any device that supports conformant OpenXR runtimes. The following is a list of known runtimes that you may want to target:
|**Runtime**|**Build target**|**Preferred Graphics API**|**Feature Parity**|**Known Limitations**|
|---|---|---|---|---|
|Windows Mixed Reality|Windows 64-bit|DX11|Full feature parity via [Mixed Reality OpenXR Plugin for Unity](https://learn.microsoft.com/en-us/windows/mixed-reality/develop/unity/mixed-reality-openxr-plugin)||
|HoloLens 2|UWP arm64|DX11|Full feature parity via [Mixed Reality OpenXR Plugin for Unity](https://learn.microsoft.com/en-us/windows/mixed-reality/develop/unity/mixed-reality-openxr-plugin)||
|Oculus PC + Link|Windows 64-bit|DX11|HMD + Controllers|Oculus Integration package features not available|
|Meta Quest|Android arm64|Vulkan|HMD + Controllers via [Meta Quest Support Feature](./features/metaquest.md)|
|Magic Leap 2|Android x64|Vulkan|Full feature parity via [Magic Leap Unity Overview OpenXR](https://developer-docs.magicleap.cloud/docs/guides/unity/unity-overview-openxr/)||
|All other conformant runtimes (eg. SteamVR)|Windows 64-bit|DX11|HMD + Controllers|Given the unbounded combinations of possible hardware/software configurations, Unity is unable to test or guarantee that all configurations will work optimally.<br><br>SteamVR Plugin features not available|
To help the community as a whole, Unity will continue to submit any runtime issues, and contribute conformance tests and specification changes to the Khronos working group.
## OpenXR Loader
Each release of the OpenXR Plugin is linked against the Khronos Group [OpenXR-SDK](https://github.com/KhronosGroup/OpenXR-SDK/releases). This repository contains the authoritative public OpenXR headers, source code and build scripts used to generate the OpenXR Loader dll/so/libraries.
This release is linked against the OpenXR-SDK version [1.1.45](https://github.com/KhronosGroup/OpenXR-SDK/releases/tag/release-1.1.45).
Additionally, you can access the current OpenXR Runtime through the scripting API via `OpenXRRuntime.version`. This returns a string representing the semantic versioning of the current OpenXR Runtime.
## Considerations before porting to OpenXR
Unity does not yet provide out-of-the-box solutions to the following when using OpenXR, however there may be platform-specific plugins or third party solutions available:
* Controller / hand models
* Finger tracking
* Augmented reality / mixed reality features
* Composition layers
* Overlays
* Foveated rendering
## Getting started
To enable OpenXR in your project, follow the steps below:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**), and select **XR Plug-in Management**.
2. Enable the **OpenXR** option and any **Feature Groups** for the runtimes you intend to target.
3. In the **OpenXR > Features** tab, select the interaction profile of the device you are testing with.
4. In the **OpenXR** tab, make sure the current active runtime is set to the hardware you are testing with. See the [Choose an OpenXR runtime to use in Play mode](xref:openxr-project-config#openxr-runtime) for more information.
See [Project configuration](xref:openxr-project-config) for additional information about setting up your project to use an OpenXR plug-in.
## Project validation
Project validation is a feature the Unity OpenXR package has to assess configuration correctness of your project depending on the platform you are planning to build for. Unity will raise errors and warnings at build time if your project is not compatible with OpenXR.
For more information on how project validation works in OpenXR, see [Project validation](xref:openxr-project-config#project-validation).
## Troubleshooting
If you experience an issue, please [file a bug](https://unity3d.com/unity/qa/bug-reporting). When you do, please also check the [log file](https://docs.unity3d.com/2021.3/Documentation/Manual/LogFiles.html) to see if Unity supports the combination of OpenXR runtimes and features you are using. The log file will provide additional guidance.
Unity generates a diagnostic log in either the Player or Editor log, depending on where you run the application. The diagnostic log starts with `==== Start Unity OpenXR Diagnostic Report ====` and ends with `==== End Unity OpenXR Diagnostic Report ====` log entries. It contains information about your application, Unity version, OpenXR runtime, OpenXR Extensions, and other aspects that can help diagnose issues.
The most important part of the diagnostic log is the section marked `==== OpenXR Support Details ====`. This section provides some simple information on what parts of your application Unity supports, what it might not support, and what to do before submitting an issue or requesting assistance.
### Examples
#### Diagnostic log OpenXR Support Details section when running with Unity supported items
```
[XR] [58328] [12:54:14.788][Info ] ==== OpenXR Support Details ====
[XR] [58328] [12:54:14.788][Info ] OpenXR Runtime:
[XR] [58328] [12:54:14.788][Info ] <Some company>, which is a Unity supported partner
[XR] [58328] [12:54:14.788][Info ] Unity OpenXR Features:
[XR] [58328] [12:54:14.788][Info ] Android , ControllerSampleValidation Standalone, Standalone : Unity
[XR] [58328] [12:54:14.788][Info ] Unity Support:
[XR] [58328] [12:54:14.788][Info ] Unity supports the runtime and Unity OpenXR Features above. When requesting assistance, please copy the OpenXR section from ==== Start Unity OpenXR Diagnostic Report ==== to ==== End Unity OpenXR Diagnostic Report ==== to the bug or forum post.
```
#### Diagnostic log OpenXR Support Details section when running with items not supported by Unity
```
[XR] [58328] [12:54:14.788][Info ] ==== OpenXR Support Details ====
[XR] [58328] [12:54:14.788][Info ] OpenXR Runtime:
[XR] [58328] [12:54:14.788][Info ] <Some company>, which is not a Unity supported partner
[XR] [58328] [12:54:14.788][Info ] Unity OpenXR Features:
[XR] [58328] [12:54:14.788][Info ] Android , ControllerSampleValidation Standalone, Standalone : Unity
[XR] [58328] [12:54:14.788][Info ] Unity Support:
[XR] [58328] [12:54:14.788][Info ] Unity doesn't support some aspects of the runtime and Unity OpenXR Features above. Please attempt to reproduce the issue with only Unity supported aspects before submitting the issue to Unity.
```
## Known issues
* For projects targeting HoloLens 2 that are using Out of the Box Unity OpenXR support, **Project Settings - &gt; Player - &gt; Resolution and Presentation - &gt; Run in Background** must be enabled. For projects that are using the Microsoft OpenXR extended support package this is not required.
* An issue with an invalid stage space during startup may cause problems with the XR Origin component from the `com.unity.xr.interaction.toolkit` package, or the camera offset component in the `com.unity.xr.legacyinputhelpers` package. These packages will be updated shortly to contain fixes for this issue. Until then the workaround is to use the `Floor` Device Tracking Option setting.
* OpenXR doesn't currently provide a way to get Acceleration and AngularAcceleration values on input devices, so these values will always be zero.
## Upgrading a project to use OpenXR
OpenXR is a plug-in in Unity's [XR plug-in architecture](https://docs.unity3d.com/2020.1/Documentation/Manual/XRPluginArchitecture.html). Unity recommends using the [XR Interaction Toolkit](https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@1.0/manual/index.html) for input and interactions. If you are using any platform-vendor specific toolkits, please see the platform-vendor specific documentation on how to integrate those toolkits with OpenXR. Vendors are still in the process of adding OpenXR support to their toolkits; please make sure you check supported status before enabling OpenXR in your project.
The core steps to upgrade a project to use OpenXR are the setup instructions at the top. In addition, you might need to do some of the following:
1. **Update to the latest [supported version](#requirements) of Unity before implementing OpenXR**. Some APIs that your project relies on might have been changed or removed, and this will let you easily distinguish which changes are a result of the new Unity version and which come from OpenXR.
2. **Disable XR SDK plug-ins that are also supported by OpenXR.** There is a good chance that OpenXR supports your target device, so enabling a competing XR SDK plug-in may cause unexpected behavior. In **Project Settings &gt; XR Plug-in Management**, uncheck the plug-in provider(s) for your target device(s).
3. **Update your input code** if your project doesn't use the new Input System. For more information, see the [Quick start guide](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/QuickStartGuide.html) in the Input System package documentation.
4. **Change quality settings.** It is possible that switching over to the OpenXR provider will affect your application's visual quality. You can adjust the quality settings of your project (menu: **Edit &gt; Project Settings &gt; Player**, then select the **Quality** tab) to try getting your old visuals back.
## OpenXR concepts
### Understanding OpenXR's action-based input
See [OpenXR Input Documentation](./input.md).
<a name="openxr-features"></a>
### OpenXR features
Features allow third parties to extend Unity's base support for OpenXR. They bring the functionality of OpenXR spec extensions to the Unity ecosystem, but Unity is not involved in their development.
Features might integrate into the [Unity XR Plug-in framework](xref:XRPluginArchitecture) to provide data to other XR subsystems (for example, providing meshing or plane data for AR use cases which are not yet standardized in OpenXR 1.0).
Features are a collection of Unity Assets that can be distributed through the Package Manager, Asset Store, or any other mechanism.
#### General features
* Mock Runtime (**Note:** Enabling this will take over whatever current OpenXR runtime you might be using.)
* [XR performance settings](./features/performance-settings.md)
#### Interaction profile features
* [Eye Gaze Interaction](./features/eyegazeinteraction.md)
* [Microsoft Hand Interaction](./features/microsofthandinteraction.md)
* [HTC Vive Controller](./features/htcvivecontrollerprofile.md)
* [Khronos Simple Controller](./features/khrsimplecontrollerprofile.md)
* [Microsoft Motion Controller](./features/microsoftmotioncontrollerprofile.md)
* [Oculus Touch Controller](./features/oculustouchcontrollerprofile.md)
* [Valve Index Controller](./features/valveindexcontrollerprofile.md)
### Accessing features at runtime via script
You can also access all the settings in the **Features** window through script. The scripting API documentation in this package provides information on all APIs you can use for feature support. The code samples below illustrate some of the common tasks.
#### Iterating over all features
```c#
BuildTargetGroup buildTargetGroup = BuildTargetGroup.Standalone;
FeatureHelpers.RefreshFeatures(buildTargetGroup);
var features = OpenXRSettings.Instance.GetFeatures();
foreach (var feature in features)
{
// Toggle feature on/off
feature.enabled = ...;
}
```
#### Getting a specific feature by type
```c#
var feature = OpenXRSettings.Instance.GetFeature<MockRuntime>();
// Toggle feature on/off
feature.enabled = ...;
```
#### Iterating over all feature groups
Feature groups are an Editor-only concept and as such can only be accessed in the Unity Editor.
```c#
#if UNITY_EDITOR
BuildTargetGroup buildTargetGroup = BuildTargetGroup.Standalone;
var featureSets = OpenXRFeatureSetManager.FeatureSetsForBuildTarget(buildTargetGroup);
foreach(var featureSet in featureSets)
{
var featureSetId = featureSet.featureSetId;
// ...
}
#endif
```
#### Iterating over features in a feature group
Feature groups are an Editor-only concept and as such can only be accessed in the Unity Editor.
```c#
#if UNITY_EDITOR
var featureSet = OpenXRFeatureSetManager.GetFeatureSetWithId(buildTargetGroup, featureSetId); // featureSetId set earlier
var features = FeatureHelpers.GetFeaturesWithIdsForActiveBuildTarget(featureSet.featureIds);
foreach (var feature in features)
{
// ... Do something with the feature.
}
#endif
```
### Implementing a feature
Anyone can add new features. To learn more, see documentation on [how to add a feature to Unity's OpenXR support](features.md).
## References
* https://www.khronos.org/openxr/
* https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html

View File

@@ -0,0 +1,228 @@
---
uid: openxr-input
---
# Input in Unity OpenXR
This page details how to use and configure OpenXR input within unity.
For information on how to configure Unity to use OpenXR input, see the [Getting Started](#getting-started) section of this document.
## Overview
Initially, Unity will provide a controller-based approach to interfacing with OpenXR. This will allow existing games and applications that are using Unity's [Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/) or the [Feature API](https://docs.unity3d.com/Manual/xr_input.html) to continue to use their existing input mechanisms.
The Unity OpenXR package provides a set of controller layouts for various devices that you can bind to your actions when using the Unity Input System. For more information, see the [Interaction profile features](./index.md#interaction-profile-features) section.
To use OpenXR Input, you must select the correct interaction profiles features to send to OpenXR. To learn more about OpenXR features in Unity, see the [Interaction profile features](./index.md#interaction-profile-features) page.
Future versions of the Unity OpenXR Package will provide further integration with the OpenXR Input system. For smooth upgrading, Unity recommends that you use the device layouts included with the OpenXR package. These have the '(OpenXR)' suffix in the Unity Input System binding window.
Unity will provide documentation on these features when they become available.
Interaction profiles manifest themselves as device layouts in the Unity [Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@latest/).
## Getting Started
### Run the sample
The Open XR package contains a sample named `Controller` that will help you get started using input in OpenXR. To install the `Controller` sample, follow these steps:
1. Open the **Package Manager** window (menu: **Window &gt; Package Manager**).
2. Select the OpenXR package in the list.
3. Expand the **Samples** list on the right.
4. Click the **Import** button next to the `Controller` sample.
This adds a `Samples` folder to your project with a Scene named `ControllerSample` that you can run.
### Locking input to the game window
Versions V1.0.0 to V1.1.0 of the Unity Input System only route data to or from XR devices to the Unity Editor while the Editor is in the **Game** view. To work around this issue, use the [Unity OpenXR Project Validator](xref:openxr-project-config#project-validation) or follow these steps:
* Access the Input System Debugger window (menu: **Window &gt; Analysis &gt; Input Debugger**).
* In the **Options** section, enable the **Lock Input to the Game Window** option.
Unity recommends that you enable the **Lock Input to the Game Window** option from either the [Unity OpenXR Project Validator](xref:openxr-project-config#project-validation) or the Input System Debugger window
![lock-input-to-game-view](images/lock-input-to-game-view.png)
### Recommendations
To set up input in your project, follow these recommendations:
* Bind to the OpenXR layouts wherever possible.
* Use specific control bindings over usages.
* Avoid generic "any controller" bindings if possible (for example, bindings to `<XRController>`).
* Use action references and avoid inline action definitions.
OpenXR Requires that all bindings be attached only once at application startup. Unity recommends the use of Input Action Assets, and Input Action References to Actions within those assets so that Unity can present those bindings to OpenXR at applications startup.
## Using OpenXR input with Unity
Using OpenXR with Unity is the same as configuring any other input device using the Unity Input System:
1. Decide on what actions and action maps you want to use to describe your gameplay, experience or menu operations
2. Create an `Input Action` Asset, or use the one included with the [Sample](#run-the-sample).
3. Add the actions and action maps you defined in step 1 in the `Input Action` Asset you decided to use in step 2.
4. Create bindings for each action.
When using OpenXR, you must either create a "Generic" binding, or use a binding to a device that Unity's OpenXR implementation specifically supports. For a list of these specific devices, see the [Interaction bindings](#interaction-bindings) section.
5. Save your `Input Action` Asset.
6. Ensure your actions and action maps are enabled at runtime.
The [Sample](#run-the-sample) contains a helper script called `Action Asset Enabler` which enables every action within an `Input Action` Asset. If you want to enable or disable specific actions and action maps, you can manage this process yourself.
7. Write code that reads data from your actions.
For more information, see the [Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/) package documentation, or consult the [Sample](#run-the-sample) to see how it reads input from various actions.
8. Enable the set of Interaction Features that your application uses.
If you want to receive input from OpenXR, the Interaction Features you enable must contain the devices you've created bindings with. For example, a binding to `<WMRSpatialController>{leftHand}/trigger` requires the Microsoft Motion Controller feature to be enabled in order for that binding to receive input. For more information on Interaction Features, see the [Interaction profile features](./index.md#interaction-profile-features) section.
9. Run your application!
You can use the Unity Input System Debugger (menu: **Window &gt; Analysis &gt; Input Debugger**) to troubleshoot any problems with input and actions.
The Input System Debugger can be found under **Window &gt; Analysis &gt; Input Debugger**
## Detailed information
### Unity Input System
Unity requires the use of the Input System package when using OpenXR. Unity automatically installs this package when you install Unity OpenXR Support. For more information, see the Input System package [documentation](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Installation.html).
### Interaction Profile Features
Each Interaction Profile Feature contains both the device layout for creating bindings in the Unity Input System and a set of bindings that we send to OpenXR. The OpenXR Runtime will determine which bindings to use based on the set of Interaction Profiles that we send to it.
Unity Recommends that Developers select only the Interaction Profiles that they are able to test their experience with.
Selecting an Interaction Profile from the features menu will add that device to the bindable devices in the Unity Input System. They will be selectable from under the **XR Controller** section of the binding options.
![XR Controller Menu](images/xr-controller-input-menu.png)
See [Set the interaction profile](xref:openxr-project-config#interaction-profile) for instructions on setting a profile.
### Mapping between OpenXR paths and Unity bindings
The OpenXR specification details a number of `Interaction Profiles` that you can use to suggest bindings to the OpenXR runtime. Unity uses its own existing XRSDK naming scheme to identify controls and devices and map OpenXR action data to them.
The table below outlines the common mappings between OpenXR paths and Unity XRSDK Control names.
Which controls are available on which devices is covered in the specific device documentation.
| OpenXR Path | Unity Control Name | Type |
|----|----|----|
|`/input/system/click`| system | Boolean |
|`/input/system/touch`| systemTouched | Boolean |
|`/input/select/click`| select | Boolean |
|`/input/menu/click`| menu | Boolean |
|`/input/squeeze/value` | grip | Float |
|`/input/squeeze/click` | gripPressed | Boolean |
|`/input/squeeze/force` | gripForce | Boolean |
|`/input/trigger/value` | trigger | Float |
|`/input/trigger/squeeze` | triggerPressed | Boolean |
|`/input/trigger/touch` | triggerTouched | Boolean |
|`/input/thumbstick`| joystick | Vector2 |
|`/input/thumbstick/touch`| joystickTouched | Vector2 |
|`/input/thumbstick/clicked`| joystickClicked | Vector2 |
|`/input/trackpad`| touchpad | Vector2 |
|`/input/trackpad/touch`| touchpadTouched | Boolean |
|`/input/trackpad/clicked` | touchpadClicked | Boolean |
|`/input/a/click` | primaryButton | Boolean |
|`/input/a/touch` | primaryTouched | Boolean |
|`/input/b/click` | secondaryButton | Boolean |
|`/input/b/touch` | secondaryTouched | Boolean |
|`/input/x/click` | primaryButton | Boolean |
|`/input/x/touch` | primaryTouched | Boolean |
|`/input/y/click` | secondaryButton | Boolean |
|`/input/y/touch` | secondaryTouched | Boolean |
the Unity control `touchpad` and `trackpad` are used interchangeably, as are `joystick` and `thumbstick`.
<a id="pose-data"></a>
### Pose data
Unity expresses Pose data as individual elements (for example, position, rotation, velocity, and so on). OpenXR expresses poses as a group of data. Unity has introduced a new type to the Input System called a `Pose` that is used to represent OpenXR poses. The available poses and their OpenXR paths are listed below:
|Pose Mapping| |
|----|----|
|`/input/grip/pose`| devicePose |
|`/input/aim/pose` | pointerPose |
For backwards compatibility, the existing individual controls will continue to be supported when using OpenXR. The mapping between OpenXR pose data and Unity Input System pose data is found below.
|Pose | Pose Element| Binding| Type|
|---|---|---|---|
|`/input/grip/pose`| position | devicePosition | Vector3|
|`/input/grip/pose`| orientation | deviceRotation | Quaternion|
|`/input/aim/pose`| position | pointerPosition | Vector3|
|`/input/aim/pose`| orientation | pointerRotation | Quaternion|
### HMD bindings
To read HMD data from OpenXR, use the existing HMD bindings available in the Unity Input System. Unity recommends binding the `centerEye` action of the `XR HMD` device for HMD tracking. The following image shows the use of `centerEye` bindings with the `Tracked Pose Driver`.
![hmd-config-tpd](images/hmd-config-tpd.png)
OpenXR HMD Data contains the following elements.
- Center Eye
- Device
- Left Eye
- Right Eye
All of the elements expose the following controls:
- position
- rotation
- velocity
- angularVelocity
These are exposed in the Unity Input System through the following bindings. These bindings can be found under the XR HMD menu option when binding actions within the Input System.
- `<XRHMD>/centerEyePosition`
- `<XRHMD>/centerEyeRotation`
- `<XRHMD>/devicePosition`
- `<XRHMD>/deviceRotation`
- `<XRHMD>/leftEyePosition`
- `<XRHMD>/leftEyeRotation`
- `<XRHMD>/rightEyePosition`
- `<XRHMD>/rightEyePosition`
When using OpenXR the `centerEye` and `device` values are identical.
The HMD position reported by Unity when using OpenXR is calculated from the currently selected Tracking Origin space within OpenXR.
The Unity `Device Tracking Origin` is mapped to `Local Space`.
The Unity `Floor Tracking Origin` is mapped to `Stage Space`.
By default, Unity attempts to attach the `Stage Space` where possible. To help manage the different tracking origins, use the `XR Origin` from the XR Interaction Package, or the `Camera Offset` component from the Legacy Input Helpers package.
### Interaction bindings
If you use OpenXR input with controllers or interactions such as eye gaze, Unity recommends that you use bindings from the Device Layouts available with the Unity OpenXR package. The Unity OpenXR package provides the following Layouts via features:
|Device|Layout|Feature|
|-----|--------|----|
|Generic XR controller|`<XRController>`|n/a|
|Generic XR controller w/ rumble support|`<XRControllerWithRumble>`|n/a|
|Windows Mixed Reality controller|`<WMRSpatialController>`|[MicrosoftMotionControllerProfile](./features/microsoftmotioncontrollerprofile.md)|
|Oculus Touch (Quest,Rift)|`<OculusTouchController>`|[OculusTouchControllerProfile](./features/oculustouchcontrollerprofile.md)|
|HTC Vive controller|`<ViveController>`|[HTC Vive Controller Profile](./features/htcvivecontrollerprofile.md)|
|Valve Index controller|`<ValveIndexController>`|[ValveIndexControllerProfile](./features/valveindexcontrollerprofile.md)|
|Khronos Simple Controller|`<KHRSimpleController>`|[KHRSimpleControllerProfile](./features/khrsimplecontrollerprofile.md)|
|Eye Gaze Interaction|`<EyeGaze>`|[EyeGazeInteraction](./features/eyegazeinteraction.md)|
|Microsoft Hand Interaction|`<HololensHand>`|[MicrosoftHandInteraction](./features/microsofthandinteraction.md)|
## Haptics
OpenXR Controllers that support haptics contain a Haptic control that you can bind to an action in the [Unity Input System](https://docs.unity3d.com/Packages/com.unity.inputsystem@latest). Set the action type to Haptic when binding an InputAction to a haptic. To send a haptic impulse, call the [OpenXRInput.SendHapticImpulse](xref:UnityEngine.XR.OpenXR.Input.OpenXRInput.SendHapticImpulse*) method and specify the InputAction that you bound to the Haptic control. You can cancel the haptic impulse by calling the [OpenXRInput.StopHaptics](UnityEngine.XR.OpenXR.Input.OpenXRInput.StopHaptics*) method.
## Debugging
For more information on debugging OpenXR input, see the [Input System Debugging](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Debugging.html) documentation.
## Future plans
Looking ahead, we will work towards allowing Unity users to leverage more functionality of OpenXR's input stack, allowing the runtime to bind Unity Actions to OpenXR Actions. This will allow OpenXR Runtimes to perform much more complex binding scenarios than currently possible.

View File

@@ -0,0 +1,262 @@
---
uid: openxr-project-config
---
# Project configuration
Use the **XR Plug-in Management** settings to configure the OpenXR plug-in for your project.
To get started, follow the instructions in [Enable the OpenXR plug-in](#enable-openxr). This also installs the OpenXR package, if needed. Once installed and enabled, you can configure your project settings as described in the [OpenXR Project settings](#project-settings) section.
You can review the [Project validation](#project-validation) section of the **XR Plug-in Management** settings to discover if any setting values are incompatible with OpenXR.
<a name="project-settings"></a>
## OpenXR Project settings
Some OpenXR features require specific Unity Project settings to function properly. The settings include:
* **[Enable the OpenXR XR plug-in](#enable-openxr)**: must be enabled to use OpenXR features.
* **[OpenXR features](#openxr-features)**: select the specific OpenXR features that you want to use.
* **[Render Mode](#render-mode)**: choose the rendering strategy.
* **[Color Submission Mode](#color-submission-mode)**: choose how color information is passed to the renderer.
* **[Depth Submission Mode](#depth-submission-mode)**: choose how depth information is passed to the renderer.
* **[Play Mode OpenXR Runtime](#openxr-runtime)** (Editor): choose which OpenXR plug-in to use when running in the Unity Editor Play mode.
* **[Interaction profiles](#interaction-profile)**: choose which OpenXR interaction profile to use for a platform.
* **[Color space](#color-space)**: When using the Open GL graphics API, you must set the **Color Space** to **Linear**.
<a name="enable-openxr"></a>
### Enable the OpenXR plug-in
To use OpenXR, you must enable the plug-in in your **XR Plug-in Management** settings. (Installing the package from the Package Manager does not automatically enable the plug-in.)
> [!NOTE]
> Enabling OpenXR also installs the package, if necessary. However, disabling OpenXR does not uninstall the package.
The **XR Plug-in Management** settings page displays a tab for each platform build target. Build support for a platform must be installed using the Unity Hub before you can enable an OpenXR plug-in for that platform. (Not every platform has a supported OpenXR plugin.) See the [Add modules](https://docs.unity3d.com/hub/manual/AddModules.html) section of the Unity Hub documentation for instructions.
To enable OpenXR:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Select **XR Plug-in Management** to view the plug-in management settings.
3. Select the tab for a platform build target to view the settings for that target.
4. Enable the **OpenXR** option in the **Plug-in Providers** list.
![XR Plug-in Management](images/openxr-xrmanagement.png "OpenXR in XR Management")<br />*Enabling OpenXR*
> [!TIP]
> If your project uses OpenXR on more than one platform build target, you must enable the OpenXR plugin for each platform.
<a name="openxr-features"></a>
### Enable OpenXR features
OpenXR plug-ins and other packages can provide optional feature implementations that you can use with OpenXR itself. For example, the Unity OpenXR plug-in provides a **Runtime Debugger** and a **Mock Runtime** as OpenXR features. After you [enable the OpenXR plug-in](#enable-openxr), you can enable any available features.
Some features are organized as a *feature group*. You can enable a feature group to enable all the features in that group.
To enable an OpenXR feature:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Click **XR Plug-in Management** to expand the plug-in section (if necessary).
3. Select **OpenXR** in the list of XR plug-ins.
4. Select the tab for a platform build target to view the features for that target.
![OpenXR features and feature groups](images/openxr-features.png "OpenXR features and feature groups")<br />*OpenXR features and feature groups*
5. Select the features and feature groups to enable.
6. Repeat for any other platform build targets your project supports.
If a feature has its own configuration options, you can click its gear icon (![](images/gear.png)) to open the feature's settings window. Some features provide an icon following their name that links to documentation.
See [OpenXR Features](index.md#openxr-features) for more information about features and groups.
<a name="render-mode"></a>
### Set the render mode
The **Render Mode** determines how OpenXR renders stereo graphics. Different plug-ins might support different modes, but the typical choices involve some form of the following:
|**Option** | **Description** |
| --------- | --------------- |
|**Multi-pass** | Each eye is rendered separately in independent *passes* from slightly different view points. Because the entire scene is rendered twice, multipass rendering is typically slower than other options. However, it is also the most similar to nonstereo rendering and does not require you to adapt your shader code. |
|**Single Pass Instanced** | Both eyes are rendered in one pass. Scene data is shared between the eyes using instanced draw calls, reducing the amount of data that must be transferred from the CPU to the GPU. Single-pass rendering is typically much faster than multi-pass, but requires compatible shaders. |
| **Single Pass Instanced / Multi-view** | Some GPU hardware supports instancing, while others support multi-view. The two render modes are otherwise very similar. If an OpenXR plug-in supports both types of hardware, you will see this option instead of the **Single Pass Instanced** option. |
To set the render mode:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Click **XR Plug-in Management** to expand the plug-in section (if necessary).
3. Select **OpenXR** in the list of XR plug-ins.
4. Select the tab for a platform build target to view the features for that target.
5. Choose the desired **Render Mode**.
For more information see:
* [SinglePassStereoMode](xref:UnityEngine.Rendering.SinglePassStereoMode)
* [Single Pass Instanced rendering](xref:SinglePassInstancing)
<a name="depth-submission-mode"></a>
### Set the color submission mode
Some OpenXR runtimes support rendering to additional swapchain formats, such as 10- or 16-bit
high-dynamic range (HDR). Alternately, some performance may be gained on some devices by choosing
lower fidelity as a trade-off. The available formats depend on both the Unity version you are using
and the device and runtime that the Player is run on.
*Auto Color Submission Mode* currently selects the default platforms which is typically an 8bpc RGBA/BGRA format.
|**Option**|**Description**|
|---|---|
|**8 bits per channel (LDR, default)**|The default 8bpc RGBA/BGRA format. Will use sRGB if supported and either default or selected in player API options (e.g. in GLES).|
|**10 bits floating-point per color channel, 2 bit alpha (HDR)**|Packed 10bpc unsigned normalized floating-point color with 2 bits of alpha depth.|
|**16 bits floating-point per channel (HDR)**|16bpc signed half-width floating point color/alpha.|
|**5,6,5 bit packed (LDR, mobile)**|Compact packed format typically only used on low performance mobile devices and low gamut displays.|
|**11,11,10 bit packed floating-point (HDR)**|Packed color-only format using 11bpc unsigned float for red and green channels and 10bpc for blue.|
The best choice depends on your use case, platform, and target devices. Larger HDR formats will
generally encounter lower performance especially on lower-spec hardware, but generally provide
better rendering integrity in scenes with high dynamic range or luminance gradients (where banding
may be noticeable in LDR formats).
Reasonable rules of thumb when choosing a setting:
* For PC XR devices, consider your target devices and choose a performant HDR setting if you need
HDR. This often depends on the graphics API, GPU, and XR device together, so it may require extra
performance testing.
* For mobile XR devices, HDR swapchains are generally unsupported. In most cases it's best to stick
to **Auto Color Submission Mode** or **8 bits per channel (LDR, default)**.
To set the color submission mode:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Click **XR Plug-in Management** to expand the plug-in section (if necessary).
3. Select **OpenXR** in the list of XR plug-ins.
4. Select the tab for a platform build target to view the features for that target.
5. Uncheck **Auto Color Submission Mode**.
6. Choose the desired **Color Submission Mode**s and sort according to priority (the order the list
is in sets the priority; actual selection depends on graphics API and hardware support.)
**8 bits per channel (LDR, default)** can be reordered but cannot be removed; it is a safe
fallback.
<a name="depth-submission-mode"></a>
### Set the depth submission mode
Many OpenXR runtimes can use depth information to perform more accurate and stable *reprojection* of content during rendering. The available **Depth Submission Modes** include:
|**Option**|**Description**|
|---|---|
|**None**|No depth submission support. No depth based stability or re-projection support that the platform might provide is enabled.|
|**Depth 16 bit**|A shared depth buffer using 16 bits per pixel is used.|
|**Depth 24 bit**|A shared depth buffer using 24 bits per pixel is used.|
The best choice can depend on the platform and specific target devices. Depth can significantly reduce judder and other XR rendering artifacts, especially with mixed reality (MR) content that combines rendered graphics with real-world video. The 16-bit option uses less bandwidth to transfer data between the CPU and GPU, which can improve rendering performance and battery life on mobile-type devices. However, the 24-bit option can minimize sorting issues and "z-fighting".
A reasonable rule of thumb to use when choosing a setting is:
* use 24-bit depth on PC XR devices
* use 16-bit depth for battery powered XR devices -- unless judder or sorting issues occur
* use **None** if your target devices don't use depth information or if you find that the benefits don't outweigh the extra rendering and battery life costs.
To set the depth submission mode:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Click **XR Plug-in Management** to expand the plug-in section (if necessary).
3. Select **OpenXR** in the list of XR plug-ins.
4. Select the tab for a platform build target to view the features for that target.
5. Choose the desired **Depth Submission Mode**.
Setting the mode to anything other than **None** enables the OpenXR [XR_KHR_composition_layer depth extension](https://www.khronos.org/registry/OpenXR/specs/1.0/html/xrspec.html#XR_KHR_composition_layer_depth). Unity ignores the **Depth Submission Mode** for OpenXR plug-ins that do not support this extension.
<a name="openxr-runtime"></a>
### Choose an OpenXR runtime to use in Play mode
By default, Unity uses the OpenXR runtime that is setup as the active runtime for your computer. You can specify a different OpenXR runtime with the **Play Mode OpenXR Runtime** setting. Unity uses the selected runtime when you run a Scene using the Editor Play mode. See [Runtime Discovery](https://www.khronos.org/registry/OpenXR/specs/1.0/loader.html#runtime-discovery) for more information about how the active OpenXR runtime is determined.
> [!NOTE]
> The **Play Mode OpenXR Runtime** setting is not saved between Editor sessions. It reverts to the **System Default** option on exit.
To set the OpenXR runtime to use in Play mode:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Click **XR Plug-in Management** to expand the plug-in section (if necessary).
3. Select **OpenXR** in the list of XR plug-ins.
4. Select the Mac, Windows, Linux settings (PC) tab.
5. Choose the desired **Play Mode OpenXR Runtime**.
The available options include the following choices:
|**Option**|**Description**|
|---|---|
|**System Default**| The active OpenXR runtime on your computer. Device makers who support OpenXR sometimes provide a utility to designate their OpenXR runtime as the active one.|
|**Windows Mixed Reality**| If available, sets the current OpenXR runtime to the Microsoft OpenXR runtime for Windows Mixed Reality.|
|**SteamVR**| If available, sets the current OpenXR runtime to the SteamVR OpenXR runtime.|
|**Oculus**| If available, sets the current OpenXR runtime to the Oculus OpenXR runtime.|
|**Other**| Specify a runtime by selecting its `json` config file on your hard drive. Choose this option to use an OpenXR runtime that Unity might not directly support or detect automatically.|
> [!TIP]
> When you hold your mouse over the drop-down control for the **Play Mode OpenXR Runtime** options, the tool-tip that pops up shows the path to selected OpenXR runtime.
<a name="interaction-profile"></a>
### Set the interaction profile
When using an OpenXR plug-in, you must specify which interaction profile to use. You can choose a profile in the **OpenXR** section of the **XR Plug-in Management** settings.
To add an OpenXR interaction profile:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Click **XR Plug-in Management** to expand the plug-in section (if necessary).
3. Select **OpenXR** in the list of XR plug-ins.
4. In the **Interaction Profiles** section, click the **+** button to add a profile.
5. Select the profile to add from the list.
![Choose Interaction Profile](images/openxr-choose-interaction-profile.png)<br />*Choose an interaction profile*
See [Input in OpenXR](xref:openxr-input) for more information.
<a name="color-space"></a>
### Set the rendering color space
When you use the OpenGL graphics API, you must set the Unity Editor to use the linear [color space](xref:LinearRendering-LinearOrGammaWorkflow).
To change the color space:
1. Open the **Project Settings** window (menu: **Edit &gt; Project Settings**).
2. Select the **Player** settings category.
3. Scroll to the **Other Settings** section. (Click **Other Settings** to open the section, if necessary.)
4. Under the **Rendering** area, choose a **Color Space**.
<a name="project-validation"></a>
## Project validation
The OpenXR package defines a set of rules for the Project Validation system. These rules check for possible incompatibilities between OpenXR and the project configuration.
Some of the rules serve as warnings for possible configuration problems; you are not required to fix these. Other rules flag configuration errors that would result in your app failing to build or not working once built. You must fix these errors.
If you have the [XR Core Utilities](https://docs.unity3d.com/Packages/com.unity.xr.core-utils@latest) 2.1.0 or later installed, you can access the Project Validation status in the **Project Settings** window under **XR Plug-in Management** (menu: **Edit &gt; Project Settings**). These results include the checks for all XR plug-ins that provide validation rules.
![project-validation](images/ProjectValidation/project-validation-core-utils.png)
You can also open a separate **OpenXR Project Validation** window for OpenXR (menu: **Window &gt; XR &gt; OpenXR &gt; Project Validation**). This window only shows the validation results related to the OpenXR plug-in and features.
![feature-validation](images/ProjectValidation/feature-validation.png)
Rules that pass validation are not shown unless you enable **Show all**.
Some rules provide a **Fix** button that updates the configuration so that the rule passes validation. Other rules provide an **Edit** button that takes you to the relevant setting so that you can make the necessary adjustments yourself.
You can enable **Ignore build errors** to bypass the pre-build validation check. However, any misconfigured features in your app might not work at runtime.
### Validation issues reported in XR Plug-in Management
![loader-with-issues](images/ProjectValidation/loader-with-issues.png)
Clicking on either the validation warning or the error icon brings up the Validation window.
### Validation issues reported in features pane
![features-with-issues](images/ProjectValidation/features-with-issues.png)
Clicking on either the validation warning or the error icon brings up the Validation window.
### Validation issues reported in build
![build-with-issues](images/ProjectValidation/build-with-issues.png)
Double-clicking on build warnings or errors from validation brings up the Validation window.

View File

@@ -0,0 +1,7 @@
{
"hideGlobalNamespace": false,
"_noIndex": false,
"useMemberPages": false,
"showScriptRef": true,
"pmdt-additional-preprocessors": "XR_COMPOSITION_LAYERS"
}

View File

@@ -0,0 +1,7 @@
---
uid: xr-plug-in-management-upgrade-guide
---
# Upgrade Guide to 0.1.2
This is a new package release. In future package versions, this page will display a list of the actions you need to take to upgrade your project to that version.

View File

@@ -0,0 +1,7 @@
---
uid: xr-plug-in-management-whats-new
---
# What's new in version 0.1.2
This is a new package release. In future package versions, this page will display a summary of updates and changes for that version.

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e0b8ad5846feb4776aea0ea91472d348
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,88 @@
using System.Collections.Generic;
using UnityEditor.Build.Reporting;
using UnityEngine.XR.OpenXR;
namespace UnityEditor.XR.OpenXR
{
/// <summary>
/// Small utility class for reading, updating and writing boot config.
/// </summary>
internal class BootConfig
{
private const string XrBootSettingsKey = "xr-boot-settings";
private readonly Dictionary<string, string> bootConfigSettings;
private readonly string buildTargetName;
public BootConfig(BuildReport report) : this(report.summary.platform)
{ }
public BootConfig(BuildTarget target)
{
bootConfigSettings = new Dictionary<string, string>();
buildTargetName = BuildPipeline.GetBuildTargetName(target);
}
public void ReadBootConfig()
{
bootConfigSettings.Clear();
string xrBootSettings = EditorUserBuildSettings.GetPlatformSettings(buildTargetName, XrBootSettingsKey);
if (!string.IsNullOrEmpty(xrBootSettings))
{
// boot settings string format
// <boot setting>:<value>[;<boot setting>:<value>]*
var bootSettings = xrBootSettings.Split(';');
foreach (var bootSetting in bootSettings)
{
var setting = bootSetting.Split(':');
if (setting.Length == 2 && !string.IsNullOrEmpty(setting[0]) && !string.IsNullOrEmpty(setting[1]))
{
bootConfigSettings.Add(setting[0], setting[1]);
}
}
}
}
public Dictionary<string, string> Settings => bootConfigSettings;
public void SetValueForKey(string key, string value) => bootConfigSettings[key] = value;
public bool TryGetValue(string key, out string value) => bootConfigSettings.TryGetValue(key, out value);
public void ClearEntryForKeyAndValue(string key, string value)
{
if (bootConfigSettings.TryGetValue(key, out string dictValue) && dictValue == value)
{
bootConfigSettings.Remove(key);
}
}
public bool CheckValuePairExists(string key, string value)
{
var foundKey = bootConfigSettings.TryGetValue(key, out string result);
return foundKey && value.Equals(result);
}
public void WriteBootConfig()
{
// boot settings string format
// <boot setting>:<value>[;<boot setting>:<value>]*
bool firstEntry = true;
var sb = new System.Text.StringBuilder();
foreach (var kvp in bootConfigSettings)
{
if (!firstEntry)
{
sb.Append(";");
}
sb.Append($"{kvp.Key}:{kvp.Value}");
firstEntry = false;
}
EditorUserBuildSettings.SetPlatformSettings(buildTargetName, XrBootSettingsKey, sb.ToString());
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 2d11a038f66347888788fed0c117d2a2
timeCreated: 1677875779

View File

@@ -0,0 +1,56 @@
using System.Linq;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.XR.Management;
using UnityEngine.XR.Management;
namespace UnityEditor.XR.OpenXR
{
[InitializeOnLoad]
internal class BuildHelperUtils : IPreprocessBuildWithReport
{
public static bool HasLoader(BuildTargetGroup targetGroup, System.Type loader)
{
var settings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(targetGroup);
if (settings)
{
#pragma warning disable CS0618
return settings.Manager.loaders.Any(loader.IsInstanceOfType);
#pragma warning restore CS0618
}
return false;
}
public int callbackOrder => -100;
public void OnPreprocessBuild(BuildReport report)
{
MakeSureXRGeneralSettingsExists(report.summary.platformGroup);
}
public static XRGeneralSettings MakeSureXRGeneralSettingsExists(BuildTargetGroup targetGroup)
{
// If we don't have XRGeneralSettings in EditorBuildSettings, check if we have one in the project and set it.
var settings = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(targetGroup);
if (!settings)
{
string searchText = "t:XRGeneralSettings";
string[] assets = AssetDatabase.FindAssets(searchText);
for (int i = 0; i < assets.Length; ++i)
{
string path = AssetDatabase.GUIDToAssetPath(assets[i]);
var allSettings = AssetDatabase.LoadAssetAtPath(path, typeof(XRGeneralSettingsPerBuildTarget)) as XRGeneralSettingsPerBuildTarget;
if (allSettings != null)
{
EditorBuildSettings.AddConfigObject(XRGeneralSettings.k_SettingsKey, allSettings, true);
break;
}
}
}
return settings;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 01028bf4492c94a2aab50778b3074bfc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 9f78bba0495c6e449b1d9a0db3a978bf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,76 @@
using System.Collections.Generic;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEditor.XR.Management;
using UnityEngine.XR.OpenXR;
namespace UnityEditor.XR.OpenXR
{
internal class UWPCoreWindowBuildHooks : IPreprocessBuildWithReport, IPostprocessBuildWithReport
{
// After MixedRealityBuildProcessor, if it's in the project.
public int callbackOrder => 2;
private static readonly Dictionary<string, string> BootVars = new Dictionary<string, string>()
{
{"force-primary-window-holographic", "1"},
{"vr-enabled", "1"},
{"xrsdk-windowsmr-library", "UnityOpenXR.dll"},
{"early-boot-windows-holographic", "1"},
};
public void OnPreprocessBuild(BuildReport report)
{
if (report.summary.platform != BuildTarget.WSAPlayer)
return;
if (!BuildHelperUtils.HasLoader(BuildTargetGroup.WSA, typeof(OpenXRLoaderBase)))
return;
var bootConfig = new BootConfig(report);
bootConfig.ReadBootConfig();
var initXRManagerOnStart = XRGeneralSettingsPerBuildTarget.XRGeneralSettingsForBuildTarget(BuildTargetGroup.WSA).InitManagerOnStart;
BootVars["vr-enabled"] = initXRManagerOnStart ? "1" : "0";
// MixedRealityBuildProcessor may skip setting `force-primary-window-holographic` in certain cases:
//
// When AppRemoting is enabled, skip the flag to force primary corewindow to be holographic (it won't be).
// If this flag exist, Unity might hit a bug that it skips rendering into the CoreWindow on the desktop.
var skipPrimaryWindowHolographic = bootConfig.TryGetValue("xrsdk-windowsmr-library", out var unused1) &&
(bootConfig.TryGetValue("vr-enabled", out var vrEnabled) && vrEnabled == "1") &&
(bootConfig.TryGetValue("early-boot-windows-holographic", out var earlyBoot) && earlyBoot == "1") &&
(!bootConfig.TryGetValue("force-primary-window-holographic", out var forceHolographic) || forceHolographic == "0");
foreach (var entry in BootVars)
{
if (entry.Key == "force-primary-window-holographic" && skipPrimaryWindowHolographic)
continue;
bootConfig.SetValueForKey(entry.Key, entry.Value);
}
bootConfig.WriteBootConfig();
}
public void OnPostprocessBuild(BuildReport report)
{
if (report.summary.platform != BuildTarget.WSAPlayer)
return;
if (!BuildHelperUtils.HasLoader(BuildTargetGroup.WSA, typeof(OpenXRLoaderBase)))
return;
// Clean up boot settings after build
BootConfig bootConfig = new BootConfig(report);
bootConfig.ReadBootConfig();
foreach (KeyValuePair<string, string> entry in BootVars)
{
bootConfig.ClearEntryForKeyAndValue(entry.Key, entry.Value);
}
bootConfig.WriteBootConfig();
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4b8db528654998e4a8a2e81f00abc149
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: bf0a3147a1827ec4baf6196d5bf7f17d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,193 @@
using System.Collections.Generic;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine;
namespace UnityEditor.XR.OpenXR.Features
{
/// <summary>
/// The Boot Config builder exposes a centralized call-site for populating BootConfig options.
/// </summary>
public class BootConfigBuilder
{
private struct SettingEntry
{
public bool IsDirty;
public string Setting;
}
private readonly Dictionary<string, SettingEntry> _bootConfigSettings;
/// <summary>
/// Internal constructor. Should only ever get called inside this assembly. More to the point, it should only ever
/// get called inside <see cref="OpenXRFeatureBuildHooks"/>
/// </summary>
internal BootConfigBuilder()
{
_bootConfigSettings = new Dictionary<string, SettingEntry>();
}
/// <summary>
/// Populate the boot config settings from the current EditorUserBuildSettings based on the BuildReport.
/// If <see cref="SetBootConfigValue"/> or <see cref="SetBootConfigBoolean"/> have been called before this call, we do not overwrite
/// the value set, as we assume that these were meant to be the new, updated values.
/// </summary>
/// <param name="report">The BuildReport load the bootconfig from.</param>
internal void ReadBootConfig(BuildReport report)
{
var bootConfig = new BootConfig(report);
bootConfig.ReadBootConfig();
foreach (var setting in bootConfig.Settings)
{
// only update the boot config if the key doesn't currently live in _bootConfigSettings
// We may have updated _bootConfigSettings before we've called `ReadBootConfig`. If that is the case,
// this value overrides what's in the boot config.
if (!_bootConfigSettings.TryGetValue(setting.Key, out var entry))
_bootConfigSettings[setting.Key] = new SettingEntry { IsDirty = false, Setting = setting.Value };
}
}
/// <summary>
/// To ensure we don't have any lingering values carried over into the next build, we clear out the current
/// boot config as part of the post build step.
/// Any setting that we have added via a <see cref="SetBootConfigValue"/> or <see cref="SetBootConfigBoolean"/> will be cleaned up.
/// Any setting that was already in the boot config will not be removed.
/// </summary>
/// <param name="report"></param>
internal void ClearAndWriteBootConfig(BuildReport report)
{
var bootConfig = new BootConfig(report);
bootConfig.ReadBootConfig();
foreach (var entry in _bootConfigSettings)
{
if (entry.Value.IsDirty)
bootConfig.ClearEntryForKeyAndValue(entry.Key, entry.Value.Setting);
}
bootConfig.WriteBootConfig();
_bootConfigSettings.Clear();
}
/// <summary>
/// Write the current boot config.
/// Since we can override the <see cref="IPostprocessBuildWithReport.OnPostprocessBuild"/>, <see cref="IPreprocessBuildWithReport.OnPreprocessBuild"/> methods,
/// we cannot guarantee this method will get called, nor the order in which this method can be called. If you override these methods,
/// unless you call the base methods last, you'll want to invoke this method manually.
/// </summary>
/// <param name="report">Build report that we want to write</param>
internal void WriteBootConfig(BuildReport report)
{
// don't bother writing out if there's no boot config settings, or there isn't an OpenXR loader active.
if (_bootConfigSettings.Count <= 0)
return;
var bootConfig = new BootConfig(report);
bootConfig.ReadBootConfig();
foreach (var entry in _bootConfigSettings)
{
// We only want to clean up the entries that we've added in this build processor.
// Any other entries, we want to leave as is.
if (entry.Value.IsDirty)
bootConfig.SetValueForKey(entry.Key, entry.Value.Setting);
}
bootConfig.WriteBootConfig();
}
/// <summary>
/// Method for setting a specific boot config option, given the key and the string value to store.
/// </summary>
/// <param name="key">Key of the value to be stored</param>
/// <param name="value">String value to write to the key</param>
/// <returns>True if we are able to set the config value, otherwise returns false</returns>
public bool SetBootConfigValue(string key, string value)
{
if (string.IsNullOrEmpty(key))
{
Debug.LogError("Cannot write a boot config value with an empty key.");
return false;
}
_bootConfigSettings[key] = new SettingEntry { IsDirty = true, Setting = value };
return true;
}
/// <summary>
/// Method for setting a specific BOOLEAN config option. This method ensures a consistent method for writing a boolean value
/// </summary>
/// <param name="key">Key of the value to be stored</param>
/// <param name="value">Boolean value to set</param>
/// <returns>If the `key` existing in the boot config and it's "1", return true. Otherwise return false.</returns>
public bool SetBootConfigBoolean(string key, bool value)
{
if (string.IsNullOrEmpty(key))
{
Debug.LogError("Cannot write a boot config with an empty key");
return false;
}
_bootConfigSettings[key] = new SettingEntry { IsDirty = true, Setting = value ? "1" : "0" };
return true;
}
/// <summary>
/// Get a config value from the boot config, given a specific key.
/// </summary>
/// <param name="key">Key we want to locate in the boot config</param>
/// <param name="value">Where we store the result.</param>
/// <returns>true if we find the key in the bootconfig, otherwise we return false</returns>
public bool TryGetBootConfigValue(string key, out string value)
{
if (string.IsNullOrEmpty(key))
{
Debug.LogError("Cannot write a boot config with an empty key");
value = null;
return false;
}
bool result = _bootConfigSettings.TryGetValue(key, out var entry);
value = result ? entry.Setting : null;
return result;
}
/// <summary>
/// Return a boolean based on the value stored at `key`
/// </summary>
/// <param name="key">key to look for in the boot config</param>
/// <param name="value">Where we store the result.</param>
/// <returns>true if we find the key in the bootconfig, otherwise we return false</returns>
public bool TryGetBootConfigBoolean(string key, out bool value)
{
if (string.IsNullOrEmpty(key))
{
Debug.LogError("Cannot perform a look up with a null or empty string key");
value = false;
return false;
}
bool result = _bootConfigSettings.TryGetValue(key, out var entry);
value = result && entry.Setting.Equals("1");
return result;
}
/// <summary>
/// Try and remove an entry from the boot config.
/// </summary>
/// <param name="key">The key to attempt to remove</param>
/// <returns>true if we were able to remove the boot config entry, otherwise false</returns>
public bool TryRemoveBootConfigEntry(string key)
{
if (string.IsNullOrEmpty(key) || !_bootConfigSettings.ContainsKey(key))
{
return false;
}
return _bootConfigSettings.Remove(key);
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 538109467cb24d89bc714edf64bef64b
timeCreated: 1680043148

View File

@@ -0,0 +1,71 @@
using UnityEditor;
using UnityEngine;
using UnityEngine.XR.OpenXR.Features.Interactions;
namespace UnityEngine.XR.OpenXR.Features.Interactions
{
[CustomEditor(typeof(DPadInteraction))]
internal class DPadInteractionCustomEditor : Editor
{
private SerializedProperty forceThresholdLeft;
private SerializedProperty forceThresholdReleaseLeft;
private SerializedProperty centerRegionLeft;
private SerializedProperty wedgeAngleLeft;
private SerializedProperty isStickyLeft;
private SerializedProperty forceThresholdRight;
private SerializedProperty forceThresholdReleaseRight;
private SerializedProperty centerRegionRight;
private SerializedProperty wedgeAngleRight;
private SerializedProperty isStickyRight;
static GUIContent s_ForceThresholdLabelLeft = EditorGUIUtility.TrTextContent("ForceThreshold");
static GUIContent s_ForceThresholdReleaseLabelLeft = EditorGUIUtility.TrTextContent("ForceThresholdRelease");
static GUIContent s_CenterRegionLeft = EditorGUIUtility.TrTextContent("centerRegion");
static GUIContent s_WedgeAngleLeft = EditorGUIUtility.TrTextContent("wedgeAngle");
static GUIContent s_IsStickyLeft = EditorGUIUtility.TrTextContent("isSticky");
static GUIContent s_ForceThresholdLabelRight = EditorGUIUtility.TrTextContent("ForceThreshold");
static GUIContent s_ForceThresholdReleaseLabelRight = EditorGUIUtility.TrTextContent("ForceThresholdRelease");
static GUIContent s_CenterRegionRight = EditorGUIUtility.TrTextContent("centerRegion");
static GUIContent s_WedgeAngleRight = EditorGUIUtility.TrTextContent("wedgeAngle");
static GUIContent s_IsStickyRight = EditorGUIUtility.TrTextContent("isSticky");
void OnEnable()
{
forceThresholdLeft = serializedObject.FindProperty("forceThresholdLeft");
forceThresholdReleaseLeft = serializedObject.FindProperty("forceThresholdReleaseLeft");
centerRegionLeft = serializedObject.FindProperty("centerRegionLeft");
wedgeAngleLeft = serializedObject.FindProperty("wedgeAngleLeft");
isStickyLeft = serializedObject.FindProperty("isStickyLeft");
forceThresholdRight = serializedObject.FindProperty("forceThresholdRight");
forceThresholdReleaseRight = serializedObject.FindProperty("forceThresholdReleaseRight");
centerRegionRight = serializedObject.FindProperty("centerRegionRight");
wedgeAngleRight = serializedObject.FindProperty("wedgeAngleRight");
isStickyRight = serializedObject.FindProperty("isStickyRight");
}
public override void OnInspectorGUI()
{
serializedObject.Update();
EditorGUILayout.LabelField("Dpad Bindings Custom Values For Left Controller:", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(forceThresholdLeft, s_ForceThresholdLabelLeft);
EditorGUILayout.PropertyField(forceThresholdReleaseLeft, s_ForceThresholdReleaseLabelLeft);
EditorGUILayout.PropertyField(centerRegionLeft, s_CenterRegionLeft);
EditorGUILayout.PropertyField(wedgeAngleLeft, s_WedgeAngleLeft);
EditorGUILayout.PropertyField(isStickyLeft, s_IsStickyLeft);
EditorGUILayout.Space();
EditorGUILayout.LabelField("Dpad Bindings Custom Values For Right Controller:", EditorStyles.boldLabel);
EditorGUILayout.PropertyField(forceThresholdRight, s_ForceThresholdLabelRight);
EditorGUILayout.PropertyField(forceThresholdReleaseRight, s_ForceThresholdReleaseLabelRight);
EditorGUILayout.PropertyField(centerRegionRight, s_CenterRegionRight);
EditorGUILayout.PropertyField(wedgeAngleRight, s_WedgeAngleRight);
EditorGUILayout.PropertyField(isStickyRight, s_IsStickyRight);
serializedObject.ApplyModifiedProperties();
}
}
}

View File

@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: 363c557b3b6241808ae890327f748be8
timeCreated: 1658880764

View File

@@ -0,0 +1,285 @@
using System;
using System.Reflection;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using UnityEngine.XR.OpenXR.Features;
using UnityEngine;
using UnityEngine.XR.OpenXR;
[assembly: InternalsVisibleTo("Unity.XR.OpenXR.Tests.Editor")]
[assembly: InternalsVisibleTo("Unity.XR.OpenXR.Tests")]
namespace UnityEditor.XR.OpenXR.Features
{
/// <summary>
/// Editor OpenXR Feature helpers.
/// </summary>
public static class FeatureHelpers
{
/// <summary>
/// Discovers all features in project and ensures that OpenXRSettings.Instance.features is up to date
/// for selected build target group.
/// </summary>
/// <param name="group">build target group to refresh</param>
public static void RefreshFeatures(BuildTargetGroup group)
{
FeatureHelpersInternal.GetAllFeatureInfo(group);
}
/// <summary>
/// Given a feature id, returns the first instance of <see cref="OpenXRFeature" /> associated with that id.
/// </summary>
/// <param name="featureId">The unique id identifying the feature</param>
/// <returns>The instance of the feature matching thd id, or null.</returns>
public static OpenXRFeature GetFeatureWithIdForActiveBuildTarget(string featureId)
{
return GetFeatureWithIdForBuildTarget(BuildPipeline.GetBuildTargetGroup(UnityEditor.EditorUserBuildSettings.activeBuildTarget), featureId);
}
/// <summary>
/// Given an array of feature ids, returns an array of matching <see cref="OpenXRFeature" /> instances.
/// </summary>
/// <param name="featureIds">Array of feature ids to match against.</param>
/// <returns>An array of all matching features.</returns>
public static OpenXRFeature[] GetFeaturesWithIdsForActiveBuildTarget(string[] featureIds)
{
return GetFeaturesWithIdsForBuildTarget(BuildPipeline.GetBuildTargetGroup(UnityEditor.EditorUserBuildSettings.activeBuildTarget), featureIds);
}
/// <summary>
/// Given a feature id, returns the first <see cref="OpenXRFeature" /> associated with that id.
/// </summary>
/// <param name="buildTargetGroup">The build target group to get the feature from.</param>
/// <param name="featureId">The unique id identifying the feature</param>
/// <returns>The instance of the feature matching thd id, or null.</returns>
public static OpenXRFeature GetFeatureWithIdForBuildTarget(BuildTargetGroup buildTargetGroup, string featureId)
{
if (String.IsNullOrEmpty(featureId))
return null;
var settings = OpenXRSettings.GetSettingsForBuildTargetGroup(buildTargetGroup);
if (settings == null)
return null;
foreach (var feature in settings.features)
{
if (String.Compare(featureId, feature.featureIdInternal, true) == 0)
return feature;
}
return null;
}
/// <summary>
/// Given an array of feature ids, returns an array of matching <see cref="OpenXRFeature" /> instances that match.
/// </summary>
/// <param name="buildTargetGroup">The build target group to get the feature from.</param>
/// <param name="featureIds">Array of feature ids to match against.</param>
/// <returns>An array of all matching features.</returns>
public static OpenXRFeature[] GetFeaturesWithIdsForBuildTarget(BuildTargetGroup buildTargetGroup, string[] featureIds)
{
List<OpenXRFeature> ret = new List<OpenXRFeature>();
if (featureIds == null || featureIds.Length == 0)
return ret.ToArray();
foreach (var featureId in featureIds)
{
var feature = GetFeatureWithIdForBuildTarget(buildTargetGroup, featureId);
if (feature != null)
ret.Add(feature);
}
return ret.ToArray();
}
}
internal static class FeatureHelpersInternal
{
public class AllFeatureInfo
{
public List<FeatureInfo> Features;
public BuildTarget[] CustomLoaderBuildTargets;
}
public enum FeatureInfoCategory
{
Feature,
Interaction
}
public struct FeatureInfo
{
public string PluginPath;
public OpenXRFeatureAttribute Attribute;
public OpenXRFeature Feature;
public FeatureInfoCategory Category;
}
private static FeatureInfoCategory DetermineExtensionCategory(string extensionCategoryString)
{
if (String.Compare(extensionCategoryString, FeatureCategory.Interaction) == 0)
{
return FeatureInfoCategory.Interaction;
}
return FeatureInfoCategory.Feature;
}
/// <summary>
/// Gets all features for group. If serialized feature instances do not exist, creates them.
/// </summary>
/// <param name="group">BuildTargetGroup to get feature information for.</param>
/// <returns>feature info</returns>
public static AllFeatureInfo GetAllFeatureInfo(BuildTargetGroup group)
{
AllFeatureInfo ret = new AllFeatureInfo { Features = new List<FeatureInfo>() };
var openXrPackageSettings = OpenXRPackageSettings.GetOrCreateInstance();
var openXrSettings = openXrPackageSettings.GetSettingsForBuildTargetGroup(group);
if (openXrSettings == null)
{
return ret;
}
var assetPath = Path.Combine(OpenXRPackageSettings.GetAssetPathForComponents(OpenXRPackageSettings.s_PackageSettingsDefaultSettingsPath), openXrPackageSettings.name + ".asset");
var openXrExtensionAssets = AssetDatabase.LoadAllAssetsAtPath(assetPath);
// Find any current extensions that are already serialized
var currentExts = new Dictionary<OpenXRFeatureAttribute, OpenXRFeature>();
var buildGroupName = group.ToString();
foreach (var ext in openXrExtensionAssets)
{
if (ext == null || !ext.name.Contains(buildGroupName))
continue;
foreach (Attribute attr in Attribute.GetCustomAttributes(ext.GetType()))
{
if (attr is OpenXRFeatureAttribute)
{
var extAttr = (OpenXRFeatureAttribute)attr;
currentExts[extAttr] = (OpenXRFeature)ext;
break;
}
}
}
// only one custom loader is allowed per platform.
string customLoaderExtName = "";
// Find any extensions that haven't yet been added to the feature list and create instances of them
List<OpenXRFeature> all = new List<OpenXRFeature>();
foreach (var extType in TypeCache.GetTypesWithAttribute<OpenXRFeatureAttribute>())
{
foreach (Attribute attr in Attribute.GetCustomAttributes(extType))
{
if (attr is OpenXRFeatureAttribute)
{
var extAttr = (OpenXRFeatureAttribute)attr;
if (extAttr.BuildTargetGroups != null && !((IList)extAttr.BuildTargetGroups).Contains(group))
continue;
if (!currentExts.TryGetValue(extAttr, out var extObj))
{
// Create a new one
extObj = (OpenXRFeature)ScriptableObject.CreateInstance(extType);
extObj.name = extType.Name + " " + group;
AssetDatabase.AddObjectToAsset(extObj, openXrSettings);
AssetDatabase.SaveAssets();
}
else
{
extObj.name = extType.Name + " " + group;
}
if (extObj == null)
continue;
bool enabled = (extObj.enabled);
var ms = MonoScript.FromScriptableObject(extObj);
var path = AssetDatabase.GetAssetPath(ms);
var dir = "";
if (!String.IsNullOrEmpty(path))
dir = Path.GetDirectoryName(path);
ret.Features.Add(new FeatureInfo()
{
PluginPath = dir,
Attribute = extAttr,
Feature = extObj,
Category = DetermineExtensionCategory(extAttr.Category)
});
if (enabled && extAttr.CustomRuntimeLoaderBuildTargets?.Length > 0)
{
if (ret.CustomLoaderBuildTargets != null && (bool)extAttr.CustomRuntimeLoaderBuildTargets?.Intersect(ret.CustomLoaderBuildTargets).Any())
{
Debug.LogError($"Only one OpenXR feature may have a custom runtime loader per platform. Disable {customLoaderExtName} or {extAttr.UiName}.");
}
ret.CustomLoaderBuildTargets = extAttr.CustomRuntimeLoaderBuildTargets?.Union(ret?.CustomLoaderBuildTargets ?? new BuildTarget[] { }).ToArray();
customLoaderExtName = extAttr.UiName;
}
all.Add(extObj);
break;
}
}
}
// Update the feature list
var originalFeatures = openXrSettings.features;
var newFeatures = all
.Where(f => f != null)
.OrderByDescending(f => f.priority)
.ThenBy(f => f.nameUi)
.ToArray();
// Populate the internal feature variables for all features
bool fieldChanged = false;
foreach (var feature in newFeatures)
{
if (feature.internalFieldsUpdated)
continue;
feature.internalFieldsUpdated = true;
foreach (var attr in feature.GetType().GetCustomAttributes<OpenXRFeatureAttribute>())
{
foreach (var sourceField in attr.GetType().GetFields())
{
var copyField = sourceField.GetCustomAttribute<OpenXRFeatureAttribute.CopyFieldAttribute>();
if (copyField == null)
continue;
var targetField = feature.GetType().GetField(copyField.FieldName,
BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
if (targetField == null)
continue;
// Only set value if value is different
if ((targetField.GetValue(feature) == null && sourceField.GetValue(attr) != null) ||
targetField.GetValue(feature) == null || targetField.GetValue(feature).Equals(sourceField.GetValue(attr)) == false)
{
targetField.SetValue(feature, sourceField.GetValue(attr));
fieldChanged = true;
}
}
}
}
// Ensure the settings are saved after the features are populated
if (fieldChanged || originalFeatures == null || originalFeatures.SequenceEqual(newFeatures) == false)
{
openXrSettings.features = newFeatures;
#if UNITY_EDITOR
EditorUtility.SetDirty(openXrSettings);
#endif
}
return ret;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 492341990ff1a774f9aec136ed15b8d6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using System;
using System.Collections.Generic;
using UnityEditor;
using UnityEditor.Build;
using UnityEditor.XR.OpenXR;
using UnityEngine;
using UnityEngine.XR.OpenXR;
namespace UnityEditor.XR.OpenXR.Features
{
internal static class KnownFeatureSetsContent
{
internal static readonly string s_MicrosoftHoloLensFeatureSetId = "com.microsoft.openxr.featureset.hololens";
internal static readonly string s_MicrosoftHoloLensTitle = "Microsoft HoloLens";
internal static readonly string s_MicrosoftHoloLensInformationText = "Enable the full suite of features for Microsoft HoloLens 2.";
internal static readonly string s_MicrosoftDownloadText = "This package must be installed. Click this icon to visit the download page for this package.";
internal static readonly string s_MicrosoftDownloadLink = "http://aka.ms/openxr-unity-install";
}
internal static class KnownFeatureSets
{
internal static Dictionary<BuildTargetGroup, OpenXRFeatureSetManager.FeatureSet[]> k_KnownFeatureSets =
new Dictionary<BuildTargetGroup, OpenXRFeatureSetManager.FeatureSet[]>()
{
{
BuildTargetGroup.WSA,
new OpenXRFeatureSetManager.FeatureSet[]
{
new OpenXRFeatureSetManager.FeatureSet() {
isEnabled = false,
name = KnownFeatureSetsContent.s_MicrosoftHoloLensTitle,
featureSetId = KnownFeatureSetsContent.s_MicrosoftHoloLensFeatureSetId,
description = KnownFeatureSetsContent.s_MicrosoftHoloLensInformationText,
downloadText = KnownFeatureSetsContent.s_MicrosoftDownloadText,
downloadLink = KnownFeatureSetsContent.s_MicrosoftDownloadLink,
},
}
},
};
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f8eb84d75a4f7f64a86d587416e11ef1
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,139 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using UnityEngine.XR.OpenXR;
namespace UnityEditor.XR.OpenXR.Features
{
internal class OpenXRChooseRuntimeLibraries : IPreprocessBuildWithReport
{
public int callbackOrder => 0;
public static string GetLoaderLibraryPath()
{
var extensions = FeatureHelpersInternal.GetAllFeatureInfo(BuildTargetGroup.Standalone);
// Loop over all the native plugin importers and find the custom loader
var importers = PluginImporter.GetAllImporters();
foreach (var importer in importers)
{
if (!importer.GetCompatibleWithEditor() || !importer.assetPath.Contains("openxr_loader"))
continue;
#if UNITY_EDITOR_WIN
if (!importer.GetCompatibleWithPlatform(BuildTarget.StandaloneWindows64) || !importer.assetPath.EndsWith(".dll"))
continue;
#elif UNITY_EDITOR_OSX
if (!importer.GetCompatibleWithPlatform(BuildTarget.StandaloneOSX) || !importer.assetPath.EndsWith(".dylib"))
continue;
#endif
bool importerPartOfExtension = false;
var root = Path.GetDirectoryName(importer.assetPath);
foreach (var extInfo in extensions.Features)
{
bool extensionContainsLoader = (root != null && root.Contains(extInfo.PluginPath));
importerPartOfExtension |= extensionContainsLoader;
bool customRuntimeLoaderOnEditorTarget = extInfo.Attribute.CustomRuntimeLoaderBuildTargets?.Intersect(
new[] { BuildTarget.StandaloneWindows64, BuildTarget.StandaloneOSX, BuildTarget.StandaloneLinux64 }).Any() ?? false;
if (extensionContainsLoader &&
customRuntimeLoaderOnEditorTarget &&
extInfo.Feature.enabled)
{
return AssetPathToAbsolutePath(importer.assetPath);
}
}
// return default loader
bool hasCustomLoader = extensions.CustomLoaderBuildTargets?.Length > 0;
if (!importerPartOfExtension && !hasCustomLoader)
return AssetPathToAbsolutePath(importer.assetPath);
}
return "";
}
private static string AssetPathToAbsolutePath(string assetPath)
{
var path = assetPath.Replace('/', Path.DirectorySeparatorChar);
if (assetPath.StartsWith("Packages"))
{
path = String.Join("" + Path.DirectorySeparatorChar, path.Split(Path.DirectorySeparatorChar).Skip(2));
return Path.Combine(PackageManager.PackageInfo.FindForAssetPath(assetPath).resolvedPath, path);
}
return path;
}
public void OnPreprocessBuild(BuildReport report)
{
var enabled = BuildHelperUtils.HasLoader(report.summary.platformGroup, typeof(OpenXRLoaderBase));
var extensions = FeatureHelpersInternal.GetAllFeatureInfo(report.summary.platformGroup);
// Keep set of seen plugins, only disable plugins that haven't been seen.
HashSet<string> seenPlugins = new HashSet<string>();
// Loop over all the native plugin importers and only include the enabled ones in the build
var importers = PluginImporter.GetAllImporters();
foreach (var importer in importers)
{
if (!importer.GetCompatibleWithPlatform(report.summary.platform))
continue;
bool loader = false;
if (importer.assetPath.Contains("openxr_loader"))
{
loader = true;
if (extensions.CustomLoaderBuildTargets?.Contains(report.summary.platform) ?? false)
importer.SetIncludeInBuildDelegate(path => false);
else
importer.SetIncludeInBuildDelegate(path => enabled);
}
if (importer.assetPath.Contains("UnityOpenXR"))
{
importer.SetIncludeInBuildDelegate(path => enabled);
}
var root = Path.GetDirectoryName(importer.assetPath);
foreach (var extInfo in extensions.Features)
{
if (root != null && root.Contains(extInfo.PluginPath))
{
if (extInfo.Feature.enabled &&
(!loader || (extInfo.Attribute.CustomRuntimeLoaderBuildTargets?.Contains(report.summary.platform) ?? false)))
{
importer.SetIncludeInBuildDelegate(path => enabled);
}
else if (!seenPlugins.Contains(importer.assetPath))
{
importer.SetIncludeInBuildDelegate(path => false);
}
seenPlugins.Add(importer.assetPath);
}
}
}
}
[InitializeOnLoadMethod]
static void InitializeOnLoad()
{
var importers = PluginImporter.GetAllImporters();
// fixes asset bundle building since IPreProcessBuildWithReport isn't called
foreach (var importer in importers)
{
if (importer.assetPath.Contains("openxr_loader"))
{
importer.SetIncludeInBuildDelegate(path => false);
}
}
}
}
}

Some files were not shown because too many files have changed in this diff Show More