"Cannot register Ray Interactor" after loading new scene

Hello,

I am getting the following error after switching from one scene to another in-game in my VR application that uses XR Interaction Toolkit.

Cannot register Ray Interactor (UnityEngine.XR.Interaction.Toolkit.XRRayInteractor) with Interaction Manager before its containing Interaction Group is registered.
UnityEngine.InputSystem.LowLevel.NativeInputRuntime/<>c__DisplayClass7_0:<set_onUpdate>b__0 (UnityEngineInternal.Input.NativeInputUpdateType,UnityEngineInternal.Input.NativeInputEventBuffer)
UnityEngineInternal.Input.NativeInputSystem:NotifyUpdate (UnityEngineInternal.Input.NativeInputUpdateType,intptr)

Does anyone know how to fix it? I haven’t found any information online except from the documentation here, which I did not find that helpful: Architecture | XR Interaction Toolkit | 2.3.2 .

Details:

  • I use VR controllers to control the app
  • I am using SceneManager.LoadSceneAsync to load the scene
  • I have XR Origin in DontDestroyOnLoad so it “moves” to the second scene when switching.
  • The error appears when I tilt the joystick on the VR controller (to aim the teleportation ray)
    • EDIT: I tried to run the appliaction more times and sometimes I can teleport but other interaction button(trigger) stops working, throwing the same error.
  • The InteractionManager is assinged in the first scene, and unassigns after the scene-switch (although present in the scene) as can be seen in the following images:

Thank you!

Okay, I read the documentation again, and read the code, too.

This solution seems to work most of the times, and if I find out how to make it work always, I’ll comment again.

I moved the XR Interaction Toolkit from Library/PackageCache to Packages so I could change the implementation.

Then I changed the implementation of function RegisterInteractor(IXRInteractor interactor) to:


public virtual void RegisterInteractor(IXRInteractor interactor)
{
    StartCoroutine(WaitTillRegistered(interactor));
}

private IEnumerator WaitTillRegistered(IXRInteractor interactor)
{
    IXRInteractionGroup containingGroup = null;
    if (interactor is IXRGroupMember groupMember)
        containingGroup = groupMember.containingGroup;

    while (containingGroup != null && !IsRegistered(containingGroup))
    {
        if (containingGroup is XRInteractionGroup group)
            group.RegisterWithInteractionManager();
        else Debug.LogError("containingGroup is NOT XRInteractionGroup group");

        Debug.LogWarning(Time.deltaTime + $"[Interactor] Waiting for registration of Interaction Group of {interactor} so it can be registered with Interaction Manager", this);
        yield return null;
    }

    if (m_Interactors.Register(interactor))
    {
        if (containingGroup != null)
            m_InteractorsInGroup.Add(interactor);

        using (m_InteractorRegisteredEventArgs.Get(out var args))
        {
            args.manager = this;
            args.interactorObject = interactor;
            args.containingGroupObject = containingGroup;
            OnRegistered(args);
        }
    }
}

And also implemetation of function RegisterInteractionGroup to:


public virtual void RegisterInteractionGroup(IXRInteractionGroup interactionGroup)
{
    StartCoroutine(WaitTillGroupRegistered(interactionGroup));
}

private IEnumerator WaitTillGroupRegistered(IXRInteractionGroup interactionGroup)
{
    IXRInteractionGroup containingGroup = null;
    if (interactionGroup is IXRGroupMember groupMember)
        containingGroup = groupMember.containingGroup;

    while (containingGroup != null && !IsRegistered(containingGroup))
    {
     
        if (containingGroup is XRInteractionGroup group)
            group.RegisterWithInteractionManager();
        else Debug.LogError("containingGroup is NOT XRInteractionGroup group");

        Debug.LogWarning(Time.deltaTime + $"[Group] Waiting for registration of Interaction Group of {interactionGroup} so it can be registered with Interaction Manager", this);
        yield return null;
    }

    if (m_InteractionGroups.Register(interactionGroup))
    {
        if (containingGroup != null)
            m_GroupsInGroup.Add(interactionGroup);

        using (m_InteractionGroupRegisteredEventArgs.Get(out var args))
        {
            args.manager = this;
            args.interactionGroupObject = interactionGroup;
            args.containingGroupObject = containingGroup;
            OnRegistered(args);
        }
    }
}

I found out that when the registration of the group the Interactor is part of doesn’t work and I take off the headset for a longer period of time (so it has to start the screen and connect to the controllers again) it registers. This doesn’t solve the problem though.

Now I added the XRInteractionManager to DontDestroyOnLoad(gameObject); in the OnEnable() function. Seems to work in the first build, I will update, if anything goes wrong.