[Solved] Scroll not working when elements inside have click events

I’m using the new Unity UI for a mobile game and in the menu I have a Scroll Rect with a Vertical Layout Group inside, with Text elements inside the group. Like this:

40868-captura-de-pantalla-2015-02-16-a-las-210150.png

The thing is that the scroll works fine until I set pointer events to the text elements (Pointer Up, Pointer Click, etc), then when I swipe above an element I think the UI is “paying attention” to the event manager i.e. checking if I release my finger to trigger Pointer Up event and therefore it does not scroll. But it still scrolls if I click outside a Text element but inside the Vertical Layout Group.

So I don’t know if there’s a way to make the group scroll even if the elements have this events.

I found what was happening! The point is that if you use Event Trigger it will eat all other inputs because it implements all the EventSystem interfaces (and the OnDrag event used by the scroll rect was eclipsed).

 namespace UnityEngine.EventSystems
 {
     [AddComponentMenu("Event/Event Trigger")]
     public class EventTrigger : MonoBehaviour, IEventSystemHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IPointerUpHandler, IPointerClickHandler, IDragHandler, IDropHandler, IScrollHandler, IUpdateSelectedHandler, ISelectHandler, IDeselectHandler, IMoveHandler
     {
         [Serializable]
         public class TriggerEvent : UnityEvent<BaseEventData>
         {
         }
 ... blah, blah, blah
}
}

So, the solution, avoid using Event Trigger, instead, implement the interface you need for the purpose. My example, instead of adding OnPointerDown and OnPointerUp using the Event Trigger I added this script to the object:

using UnityEngine;
using System.Collections;
using UnityEngine.EventSystems;

public class Click : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {

	public void OnPointerDown (PointerEventData eventData) {
		// Do action
	}

	public void OnPointerUp (PointerEventData eventData) {
		// Do action
	}
}

When I try this implementation:

public class Click : MonoBehaviour, IPointerDownHandler, IPointerUpHandler {

 public void OnPointerDown (PointerEventData eventData) {
     // Do action
 }

 public void OnPointerUp (PointerEventData eventData) {
     // Do action
 }

}

On mobile device OnPointerUp event is triggered almost same time as OnPointerDown,
so can’t do anything with this implementation, am I doing something wrong?

A simpler solution is to just use a button. I deleted the EventTrigger components and replaced them with simple Button components and this allowed the Image component to remain clickable and propagated the scroll event up to the ScrollRect game object, so the scrolling action now works when users scroll over the image.

If Marucu’s solution didn’t work out for you or you simply don’t like the idea of getting rid of your Trigger Events, FEAR NOT MY BROTHER (or sister/wtv u want), I HAVE A SOLUTION!

In a nutshell, my solution was simply to detect if the user is hovering over said element using a boolean. Afterwards, I would simply apply any scroll inputs directly to the RectTransform of the whole scrollable container. You can multiply this input by whatever you want.

I know it sounds dumb, but think about it, think about it deeply.
Is it really?

Anyhow, here’s a simple example script:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class temp : MonoBehaviour
{
    public RectTransform yourScrollboxContainer;
    public bool isHoveringOverUI = false;
    public int scrollSensitivity = 200;

    void Update()
    {
        if(isHoveringOverUI && Input.GetAxisRaw("Mouse ScrollWheel") != 0){
            yourScrollboxContainer.anchoredPosition = new Vector2(0, yourScrollboxContainer.anchoredPosition.y - Input.GetAxisRaw("Mouse ScrollWheel") * scrollSensitivity);
        }
    }

    //Set your PointerEnter event to this
    public void TriggerEventPointerEnter(){
        isHoveringOverUI = true;
    }

    //Set your PointerExit event to this
    public void TriggerEventPointerExit(){
        isHoveringOverUI = false;
    }
}

I don’t t know if this is a little extreme, I honestly don’t really care.
It gets the job done, and gives you as much control as you want over the thing.
You’re welcome :wink: