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

How to disable grab and scroll on UI elements #32

Closed
wirelessdreamer opened this issue Mar 8, 2018 · 8 comments
Closed

How to disable grab and scroll on UI elements #32

wirelessdreamer opened this issue Mar 8, 2018 · 8 comments

Comments

@wirelessdreamer
Copy link

With UI elements that have a vertical or horizontal scroll box, and trying to click on items in the scroll box, the only consistant way I've found many users are able to click on them is with higher pose easer, and pose stabalizer script values, but that makes the ui feel very sluggish.

The issue stems from as most users are clicking, their cursor is moving a tiny about, we're using the touchpad scrolling on the background fore movement, and have no need of the cursor grab and scroll on the background, though we use it on the slider on the right side of the list.

What is a clean way to fully disable the grab and scroll, and to send the click event before the full button click happens? I've been digging through the code, but haven't found the section that controls when the selection event happens, that should be enough of a workaround for me to be able to resolve the current issue i'm troubleshooting.

@lawwong
Copy link
Collaborator

lawwong commented Mar 9, 2018

Do you mean disable ScrollRect dragging only?
You may try this
https://forum.unity.com/threads/scroll-rect-disable-dragging.303841/

@lawwong
Copy link
Collaborator

lawwong commented Mar 9, 2018

For example

using UnityEngine.EventSystems;
using UnityEngine.UI;

public class NoDragScrollRect : ScrollRect
{
    public override void OnBeginDrag(PointerEventData eventData) { }
    public override void OnDrag(PointerEventData eventData) { }
    public override void OnEndDrag(PointerEventData eventData) { }
}

You can even keep the editor

using UnityEditor;
using UnityEditor.UI;

[CustomEditor(typeof(NoDragScrollRect))]
public class NoDragScrollRectEditor : ScrollRectEditor { }

@wirelessdreamer
Copy link
Author

wirelessdreamer commented Mar 9, 2018

Thanks for the quick reply. I just tried that solution, and result from it still doesn't give the behavior i'm trying to get, its still awkward for users to select elements on a large list. The best solution would be to be able to send the click even sooner on button press, like having a limit on the analog trigger, and sending the button press before the button is all the way down, I'm just not sure how to implement that with this framework. in VRTK there was an option to use trigger touch instead of trigger click.

@lawwong
Copy link
Collaborator

lawwong commented Mar 10, 2018

If you are using VivePointers prefab, find ViveRaycaster component under VivePointers>Right/Left>PoseTracker>EventRaycaster .
Here you can change behavior to emit "Mouse Button Left" event.
You may try Trigger, TriggerTouch, HairTrigger, FullTrigger to see which behavior works better for user.

@wirelessdreamer
Copy link
Author

I've tested a couple different times, and am not noticing the behavior change no matter which type of trigger input I select.

@wirelessdreamer
Copy link
Author

I found a better way to clarify the issue.
open example 7: RoleBindingExample

define your controller, and change the Event Raycaster Mouse button left to any of the trigger function. They all only fire after the trigger has been released. The solution to the issue is to fire the click even as soon as the trigger starts moving down, as opposed to only on release.

Where would be the right place to update the plugin so one of the options for input can fire when the trigger starts to move down, instead of just be released

if you point at the plus button to add a controller and start to click, but the cursor leaves the plus before it is released, no click is registered, which can provide a confusing experience for users, when they care about clicking on what they are pointing at when the start to pull the trigger.

@lawwong
Copy link
Collaborator

lawwong commented Mar 21, 2018

I think I got it.

Just invoke event in UnityEngine.UI.Button.IPointerDownHandler

using System;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public class PointerDownButton : Button
{
    [Serializable]
    public class ButtonDownEvent : UnityEvent { }

    [SerializeField]
    private ButtonDownEvent m_onDown = new ButtonDownEvent();

    public ButtonDownEvent onDown { get { return m_onDown; } set { m_onDown = value; } }

    public override void OnPointerDown(PointerEventData eventData)
    {
        base.OnPointerDown(eventData);
        if (!IsActive() || !IsInteractable()) { return; }
        m_onDown.Invoke();
    }
}

Add editor as well

using UnityEditor;
using UnityEditor.UI;

[CustomEditor(typeof(PointerDownButton), true)]
[CanEditMultipleObjects]
public class PointerDownButtonEditor : ButtonEditor
{
    SerializedProperty m_onDownProperty;

    protected override void OnEnable()
    {
        base.OnEnable();
        m_onDownProperty = serializedObject.FindProperty("m_onDown");
    }

    public override void OnInspectorGUI()
    {
        base.OnInspectorGUI();

        serializedObject.Update();
        EditorGUILayout.PropertyField(m_onDownProperty);
        serializedObject.ApplyModifiedProperties();
    }
}

The reason why UnityEngine.UI.Button doesn't fit your use case is because it implement IPointerClickHandler, and the behavior you described is exactly what PointerClick event designed to be. See Standalone Input Module Source Code for the origin implementation.

There are more handlers you can manipulate with.
Additionally, VIU v1.7.1 added 2 handlers that origin handlers can't provide:

  • Pointer3D.IPointer3DPressEnterHandler
    • It's like IPointerEnterHandler, instead it happens when both pointer moved in and the related button is pressed.
  • Pointer3D.IPointer3DPressExitHandler
    • It's like IPointerExitHandler, instead it happens when pointer moved out or the related button is released.

@wirelessdreamer
Copy link
Author

We implemented something very similar to this as a workaround last week. We'll take our workaround as the right solution then. Thanks :)

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

No branches or pull requests

2 participants