Search Unity

Feedback XR Interaction Toolkit: XRBaseInteractable.OnDeactivate before XRBaseInteractable.OnSelectExited?

Discussion in 'XR Interaction Toolkit and Input' started by langokalla, Apr 26, 2021.

  1. langokalla

    langokalla

    Joined:
    Aug 4, 2020
    Posts:
    22
    If an interactable is selected and activated through OnSelectEntered and OnActivated, and this interactable then is unselected through OnSelectExited the OnDeactivated is not called. Is this intended behaviour?

    Example class
    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.XR.Interaction.Toolkit;
    3.  
    4. public class OnDeactivatedExample : XRBaseInteractable
    5. {
    6.     protected override void OnSelectEntered(SelectEnterEventArgs args)
    7.     {
    8.         base.OnSelectEntered(args);
    9.         Debug.Log("Interactable Selected");
    10.     }
    11.  
    12.     protected override void OnSelectExited(SelectExitEventArgs args)
    13.     {
    14.         base.OnSelectExited(args);
    15.         Debug.Log("Interactable Unselected");
    16.     }
    17.  
    18.     protected override void OnActivated(ActivateEventArgs args)
    19.     {
    20.         base.OnActivated(args);
    21.         Debug.Log("Interactable Activated");
    22.     }
    23.  
    24.     protected override void OnDeactivated(DeactivateEventArgs args)
    25.     {
    26.         base.OnDeactivated(args);
    27.         Debug.Log("Interactable Deactivated");
    28.     }
    29. }

    Behaviour observed when using this script on a gameobject:
    1. Select interactable
      1. Calls OnSelectEntered and logs "Interactable Selected".
    2. Activate interactable
      1. Calls OnActivatedEntered and logs "Interactable Activated".
    3. Unselect interactable
      1. Calls OnSelectExited and logs "Interactable Unselected"
    OnDeactivated is never called and "Interactable Deactivated" never logged.

    What I expected when diving into this was:
    1. Select interactable
      1. Calls OnSelectEntered and logs "Interactable Selected".
    2. Activate interactable
      1. Calls OnActivatedEntered and logs "Interactable Activated".
    3. Unselect interactable
      1. Calls OnDeactivated and logs "Interactable Deactivated" (either before or after the next line)
      2. Calls OnSelectExited and logs "Interactable Unselected"


    Seems intuitive that a selected and activated object also should be deactivated when it is unselected. Workaround is easy to make, however for me it feels like this should be part of the XRBaseInteractable. Thoughts or explanations on why this is?

    Unity 2020.3.5f (LTS),
    XR Interaction Toolkit 1.0.0-pre.3
    Input System 1.0.2

    Set up with an Action based XR Rig and controllers.
     
    Last edited: Apr 27, 2021
  2. calebcannon

    calebcannon

    Joined:
    Oct 6, 2021
    Posts:
    1
    I'm seeing similar behavior 2.1.0-pre as well. Seems that OnDeactivated is only called if the object is actively selected. That's fine if the object is implicitly deactivated when deselected, but we can get some out of sequence callbacks by deselecting before deactivating. In the simplest case I can get a deactivate callback after deselecting the reselecting:

    Code (csharp):
    1. Input Action                Unity Callback
    2. -------------------------------------------
    3. Hover                      OnHoverEntered
    4. Press Grip                 OnSelectEntered
    5. Press Trigger              OnActivated
    6. Release Grip               OnSelectExit <-- we're deselecting then reselecting here
    7. Press Grip                 OnSelectEnter
    8. Release Trigger            OnDeactivated
    9. Unhover                    OnHoverExited
    If I don't reselect then OnDeactivated is not called and I can get multiple OnActivated callbacks without receiving a deactivated callback

    Code (csharp):
    1. Input Action                Unity Callback
    2. -------------------------------------------
    3. Hover                      OnHoverEntered
    4. Press Grip                 OnSelectEntered
    5. Press Trigger              OnActivated
    6. Release Grip               OnSelectExit
    7. Release Trigger                         <--  no callback here
    8. Press Grip                 OnSelectEnter
    9. Press Trigger              OnActivated  <-- Second OnActivate without OnDeactivate
    10. Release Trigger            OnDeactivated
    11. Unhover                    OnHoverExited
    Finally, I can get a way out of sequence OnDeactivated callback by selecting and activating then deselecting object 1, selecting then deselecting object 2, and finally selecting then deactivating object 1 again. OnDeactivate is called when the trigger is released, even after a second object has been selected and then deselected.
     
    langokalla likes this.