Showing results for 
Search instead for 
Did you mean: 

OpenXR interaction profile quirks in Unity

Honored Guest
This is not a post about using Unity for Meta OpenXR development - more a lower-level question about how Unity's OpenXR implementation is interacting with the Meta runtime (specifically the Android/Quest runtime). Unity applies its own cross-backend action-based input layer onto OpenXR input. It doesn't really utilise OpenXR input, actions, suggested bindings etc in the spirit of their design, but as far as I can see the use should still be valid. However, this seems to me to be triggering a quirk in the runtime. My understanding is Unity's implementation works like this:
- App configures Unity with a list of 'supported interaction profiles'
- Unity creates one XrActionSet set per supported profile
- For each supported profile, Unity creates a bunch of XrActions based on the profile, adding them to the XrActionSet corresponding to that profile (created in the step above) 
- Unity calls xrSuggestInteractionProfileBindings for each supported profile suggesting bindings (for that profile only) for said bunch of XrActions (created above specifically for that profile)
- Unity attaches all XrActionsSets (one for each supported profile) to the session
- Every frame, regardless of the current interaction profile at each user path, Unity calls xrSyncActions specifying an XrActiveActionSet for every XrActionSet that has been created (one for each supported profile), for every subaction path it is valid for (typically both /user/hand/left and /user/hand/right).
So, for instance, a typical setup might list Oculus Touch Controller and Microsoft Hand Interaction as supported profiles. You end up with one set for each. Each action set contains a bunch of actions corresponding exactly to the inputs defined in those profiles. Unity calls xrSyncActions once per frame, specifying 4 XrActiveActionSets:
- The 'Oculus Touch Controller' action set for subaction path '/user/hand/left'
- The 'Oculus Touch Controller' action set for subaction path '/user/hand/right'
- The 'Microsoft Hand Interaction' action set for subaction path '/user/hand/left'
- The 'Microsoft Hand Interaction' action set for subaction path '/user/hand/right'
While there are no current interaction profiles (i.e. no active controllers and no detected hands), the call to xrSyncActions succeeds. As soon as there is a current interaction profile (on either hand), xrSyncActions - with the exact same input - starts to fail with XR_ERROR_PATH_UNSUPPORTED. As a result, all subsequent xrGetActionState* calls return empty data (since actions have not been synced) and input is completely broken.
The failed calls to xrSyncActions correspond to logcat entries that look like: "[OpenXR_Actions] unsupportedpath; actionset doesn't contain a binding for the requested subaction path;". The actions for the profile that is not currently active are then logged out as though they are responsible. i.e., if Oculus Touch Controller is current at /user/hand/left, the XrActiveActionSet that specifies /user/hand/left with the action set created for the Microsoft Hand Interaction profile is blamed, and vice versa. Typically, this manifests on both the left and right hands at once, but not always (you might have only one controller connected so one hand has no active interaction profile at times when the other does).
Note the example setup above is just an example. It is replicable with any combination of more than one interaction profile. With only one profile (e.g. if you were to use only 'Oculus Touch Controller' or 'Microsoft Hand Interaction' in isolation), everything works as you'd expect. This doesn't seem to be an issue when using the desktop runtime ('Microsoft Hand Interaction' isn't supported there for some reason, but you can test this out with any two profiles).
This feels like a bug in the Quest runtime to me. At the very least, it is different to every other runtime where Unity's unusual approach seems to work. The result doesn't make sense according to the OpenXR spec, which says of xrSyncActions: "If the subaction path was not specified on any of the actions in the actionSet when that action was created, the runtime must return XR_ERROR_PATH_UNSUPPORTED". In this case, each specified action set definitely contains at least one action created with the specified subaction path.
While it's true that for some of the specified action sets there is no current binding for any action within the set (since the sets and their actions are profile specific), that should not be a fail scenario, the actions should just be inactive in subsequent calls to xrGetActionState*. If this failure is valid then surely xrSyncActions should also fail in the same way when there are NO current interaction profiles, but this isn't the case.
Anyone else seen this behaviour and/or know whether it is correct or not? If you were writing a native OpenXR app targeting Quest you'd likely have app-specific actions with suggested bindings across multiple interaction profiles - at least one of which the runtime would understand - and so I suspect you probably wouldn't come across this, but that doesn't mean Unity's use is invalid.

Honored Guest

Just wanted to note that this does appear to have been a bug and it was fixed in runtime version 57, or perhaps 1/2 versions before (I don't have access to every older runtime build to check). The same Unity binary that produces bulk XR_ERROR_PATH_UNSUPPORTED errors and has broken input on runtime v53 (which I do have access to, pictured below) works as expected on the latest v57 runtime.



Honored Guest


It seems that I have the same issue. My Unity Editor is crashing almost all the time.

How do I have to proceed to fix it ?

Thanks in advance,