Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable pointers from code #5920

Merged

Conversation

julenka
Copy link
Contributor

@julenka julenka commented Sep 10, 2019

Overview

We have had many requests for how to disable the far interaction (line pointer, hand rays, etc) at runtime. For example, this stackoverflow question.

The default way to do this is not obvious, and requires creating a custom mediator. This change provides a way for people using the default FocusProvider and DefaultPointerMediator to dynamically enable and disable pointers at runtime. Pointers can be enabled / disabled per handedness as well, allowing you to, for example, turn off hand rays for the right hand only.

Developers turn pointers on and off by specifying the PointerBehavior for a pointer type. PointerBehavior is defined as follows:

    /// <summary>
    /// Specifies how a pointer in MRTK's default input system behaves.
    /// By default, pointer behaviors are set to Default.
    /// </summary>
    public enum PointerBehavior
    {
        /// <summary>
        /// Pointer active state is managed by MRTK input system. If it is a near pointer (grab, poke), it
        /// will be always enabled. If it is not a near pointer, it will get disabled if any near pointer on the 
        /// same hand is active. This is what allows rays to turn off when a hand is near a grabbable.
        /// </summary>
        Default,
        /// <summary>
        /// Pointer is always on, regardless of what other pointers are active.
        /// </summary>
        AlwaysOn,
        /// <summary>
        /// Pointer is always off, regardless of what other pointers are active.
        /// </summary>
        AlwaysOff
    };

Here is an example of dynamically turning different pointers on / off:

pointerOnOff

Changes

  • Fixes: Make it easy to enable / disable hand rays/gaze cursor/other pointers at runtime #4954
  • Introduce PointerBehavior to describe how pointer should behave: On, Off, Default (use MRTK Rules: gaze is off if hand rays on, hand rays off if they are near grabbable)
  • Provide API in FocusProvider to set the pointer behavior for a pointer type and handedness
  • Provide convenience methods in PointerUtils to set common pointer behaviors
  • Add tests
  • Add example scene
  • Add documentation

Old way to turn pointers on off

See this stackoverflow question, it requires creating custom pointer mediator.

New way to turn pointers on / off

// Turn off all hand rays
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

// Restore default behavior for rays (on if not near something grabbable)
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.Default);

// Turn off hand rays for the right hand only
PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Right);

// Turn off the gaze pointer
PointerUtils.SetGazePointerBehavior(PointerBehavior.AlwaysOff);

Verification

  • Works on VR, able to disable hand rays / controller rays separately
  • Works on HL1
  • Works on HL2

@julenka
Copy link
Contributor Author

julenka commented Sep 10, 2019

Still TO DO in this PR:

  • Verify works on HL1, HL2
  • Add tests for gaze, grab, poke pointers, and common modes.

Copy link
Contributor

@Troy-Ferrell Troy-Ferrell left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great stuff! Super excited to finally give this power to developers. Most comments are minor nits/suggestions.

The only thing that scares me is the actual enum. Now realizing that On actually means AlwaysOn. I am worried that developers will set the values On/Off and not Default/Off. Like oh, I want this pointer to be on...and do it's default thing.

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@julenka julenka changed the title Turn rays, grab, gaze pointers on and off at runtime from code Disable pointers from code Sep 12, 2019
@julenka
Copy link
Contributor Author

julenka commented Sep 12, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@julenka
Copy link
Contributor Author

julenka commented Sep 12, 2019

/azp run

@julenka julenka closed this Sep 12, 2019
@julenka julenka reopened this Sep 12, 2019
@julenka
Copy link
Contributor Author

julenka commented Sep 12, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@julenka
Copy link
Contributor Author

julenka commented Sep 12, 2019

/azp run

@azure-pipelines
Copy link

Azure Pipelines successfully started running 2 pipeline(s).

@julenka julenka dismissed Troy-Ferrell’s stale review September 12, 2019 21:58

Troy says changes are good but isn't available to approve, so dismissing review

@julenka julenka merged commit 1a011ec into microsoft:mrtk_development Sep 12, 2019
@julenka julenka mentioned this pull request Sep 18, 2019
@pampas93
Copy link

pampas93 commented Jan 20, 2020

Is it the expected behavior to not receive any IMixedRealityPointerHandler callbacks after switching off HandRayPointer?
using PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

@sostel
Copy link
Contributor

sostel commented Jan 21, 2020

Is it the expected behavior to not receive any IMixedRealityPointerHandler callbacks after switching off HandRayPointer?
using PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

If you turn off the HandRayPointer and you may have to enable an alternative pointer. For example:

public void DisableHandRay()
        {
            PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
            PointerUtils.SetGazePointerBehavior(PointerBehavior.Default);
        }

@pampas93
Copy link

pampas93 commented Jan 26, 2020

Is it the expected behavior to not receive any IMixedRealityPointerHandler callbacks after switching off HandRayPointer?
using PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff);

If you turn off the HandRayPointer and you may have to enable an alternative pointer. For example:

public void DisableHandRay()
        {
            PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
            PointerUtils.SetGazePointerBehavior(PointerBehavior.Default);
        }

With the GazePointer enabled and the HandRayPointer disabled, I still get the same behavior. No callbacks to the IMixedRealityPointerHandler functions.

For example, the log is never printed (with the below type of code). With the class implementing IMixedRealityPointerHandler interface. But commenting out the SetHandRayPointerBehavior works fine.

void OnEnable()
{
    PointerUtils.SetHandRayPointerBehavior(PointerBehavior.AlwaysOff, Handedness.Any);
    PointerUtils.SetGazePointerBehavior(PointerBehavior.Default);
}

public void OnPointerDown(MixedRealityPointerEventData eventData)
{
    Debug.Log("Pointer down");
}

Tested on the sample scene (DisablePointersExample) too

@Troy-Ferrell
Copy link
Contributor

@pampas93 how are you activating the pointer down event with the gaze pointer?

@pampas93
Copy link

@pampas93 how are you activating the pointer down event with the gaze pointer?

I'm implementing the IMixedRealityPointerHandler and registering the handler with the CoreServices.InputSystem within the OnEnable of the script

@Troy-Ferrell
Copy link
Contributor

@pampas93 no sorry I meant at runtime,are you just running in editor with gaze provided or on device? Do you look at the item with the script and say select with voice?

@pampas93
Copy link

I'm running this on the editor, with the hand visualized (input simulation). But I didn't get your second question. I'm not using any interactable script on the item to have it say select with voice.

@Troy-Ferrell
Copy link
Contributor

@pampas93 Ok I think I know what is going on. The reason why you are not getting a OnPointerDown event is because there is no pointer to fire it.

You disable the hand ray pointer via PointerUtils.SetHandRayPointerBehavior() so that will no longer fire the events or be an active pointer.

The GazePointer (GGVPointer) actually isn't active by default in editor. This is because by default the pointer is only created for "GGV Hand" input sources/controllers.
image

I know this is a bit weird, but basically this type of "GGV Hand" will only show up on HL1. In editor and HL2, the type of hand created is "Articulated Hand" which only spawns the hand ray pointer and grab/poke pointers.

I created a new issue #7182 to track making this more apparent in the API

@dahaideyu
Copy link

How to close TeleportPointer and ParabolicTeleportPointer ,Use code is not work
PointerUtils.SetPointerBehavior(PointerBehavior.AlwaysOff);

		PointerUtils.SetPointerBehavior<ParabolicTeleportPointer>(PointerBehavior.AlwaysOff); @julenka 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Make it easy to enable / disable hand rays/gaze cursor/other pointers at runtime
7 participants