Jump to content

Vive Focus 3 Input bug with OpenXR & Unity


Remio

Recommended Posts

I am having an issue with using OpenXR for Unity android build. Input does not seem to fully register upon starting the app. Some controls work and some don't, and there is a null reference spam when checking the console logs:

2022/11/03 08:04:48.269 4196 4222 Error Unity NullReferenceException: Object reference not set to an instance of an object.
2022/11/03 08:04:48.269 4196 4222 Error Unity   at UnityEngine.InputSystem.InputActionState.ApplyProcessors[TValue] (System.Int32 bindingIndex, TValue value, UnityEngine.InputSystem.InputControl`1[TValue] controlOfType) [0x00000] in <00000000000000000000000000000000>:0 
2022/11/03 08:04:48.269 4196 4222 Error Unity   at UnityEngine.InputSystem.InputAction.ReadValue[TValue] () [0x00000] in <00000000000000000000000000000000>:0 
2022/11/03 08:04:48.269 4196 4222 Error Unity   at UnityEngine.XR.Interaction.Toolkit.ActionBasedSnapTurnProvider.ReadInput () [0x00000] in <00000000000000000000000000000000>:0 
2022/11/03 08:04:48.269 4196 4222 Error Unity   at UnityEngine.XR.Interaction.Toolkit.SnapTurnProviderBase.Update () [0x00000] in <00000000000000000000000000000000>:0 

Weirdly enough, this error only occurs on first time use of the app. When restarting the app everything works fine, all inputs register and no errors. If I restart the headset or reinstall the app, the error reappears. I'm wondering if there's something I'm missing initialization related for OpenXR loader? Been searching through the codebase and settings and cannot find anything

 

Using Unity 2021.3.8f1,  OpenXR 1.5.3 with Unity's Input System 1.4.2 with these settings:

 

Screenshot 2022-11-03 110050.png

Screenshot 2022-11-03 110105.png

Link to comment
Share on other sites

Hi @Remio,

Sorry to hear that there's some trouble.

To jump ahead a bit - I believe I have a workaround that should work for you:

The ActionBasedSnapTurnProvider component should be enabled only after the xr subsystem is fully registered. So try turning it off by default with another component similar to the one below. Create this script and attach it to the same gameobject as the ActionBasedSnapTurn provider and it will turn it on only after the xr system is active:

using System;
using System.Collections;
using UnityEngine;
using UnityEngine.XR.Interaction.Toolkit;
using UnityEngine.XR.Management;

[RequireComponent(typeof(ActionBasedSnapTurnProvider))]
public class WorkaroundInputBugActionBasedSnapTurnProvider : MonoBehaviour
{
    private ActionBasedSnapTurnProvider m_SnapTurnProvider;
    private IEnumerator m_WaitForXRSystemEnumerator;
    
    private bool IsXRSystemActive()
    {
        if (XRGeneralSettings.Instance == null || XRGeneralSettings.Instance.Manager == null)
        {
            return false;
        }
        return XRGeneralSettings.Instance.Manager.isInitializationComplete;
    }
    public void OnEnable()
    {
        if (m_SnapTurnProvider == null)
        {
            m_SnapTurnProvider = GetComponent<ActionBasedSnapTurnProvider>();
        }

        bool isXRSystemActive = IsXRSystemActive();
        Action OnXRSystemActive = () =>
        {
            if (m_SnapTurnProvider == null) throw new Exception("Snap turn provider deleted");
            m_SnapTurnProvider.enabled = true;
        };
        if (isXRSystemActive)
        {
            OnXRSystemActive.Invoke();
        }
        else
        {
            m_SnapTurnProvider.enabled = false; //disable component, as it will throw exceptions while xr system is not active

            if (m_WaitForXRSystemEnumerator == null)
            {
                m_WaitForXRSystemEnumerator = WaitForXRSystem(OnXRSystemActive);
                StartCoroutine(m_WaitForXRSystemEnumerator);
            }            
        }

    }

    IEnumerator WaitForXRSystem(Action onInitComplete)
    {
        while (XRGeneralSettings.Instance == null || XRGeneralSettings.Instance.Manager == null)
        {
            yield return null;
        }
        while (!XRGeneralSettings.Instance.Manager.isInitializationComplete)
        {
            yield return null;
        }
        
        onInitComplete?.Invoke();
    }
}




My belief at the end of this is that this is a legitimate bug that should be submitted to unity, as it is a clear bug in the way that processors work in the input system - it seems that either
A) dependency of the input system being initialized should be checked before querying the input system
or more likely
B) the processors should not throw null reference exceptions if the input returns null (or is not yet initialized, as in this case)

This is an interesting problem, so let's unpack this  together and see if those conclusions ring true for you as well:

1)The input system package doesn't seem to have any fixes for possibility B in the "known issues" of their latest input system package here https://docs.unity3d.com/Packages/com.unity.inputsystem@1.4/changelog/CHANGELOG.html
2)There could be a check to make sure the xr subsystem is enabled in the ActionBasedSnapTurnProvider class, which is a part of the XR interaction toolkit package. Looking at the changelog, I'm not seeing any potential fixes in newer versions. https://docs.unity3d.com/Packages/com.unity.xr.interaction.toolkit@2.2/changelog/CHANGELOG.html While I don't think the correct fix would be in this package, I wanted to at least check to see if that is the solution that was used.
3) The error comes from processing the processor on an input, which should not null reference - this seems to support the idea that it is an issue with the input system package itself - in the way the processor runs without proper null checks https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/manual/Processors.html
4) The xr subsystem is not guaranteed to be running at the first frame If it takes more frames than usual to initialize the xr subsystems, then the app should behave normally. This can be done manually in a manner similar to the workaround posted above - by polling the unity apis to check if the xr subsystem should work. This will allow us to workaround this bug (which is likely #1 above)
5) I have seen the app take longer than the usual 3 frames to initialize on the first launch

This looks like a great candidate to post to the unity bug reporter at https://unity3d.com/unity/qa/bug-reporting 

Thanks for posting!
Let me know if this helps and/or if there is anything else.

Thanks,
Alex

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...