For the first time using UGUI to develop the nest layout, very easy to arrange the basic UI elements,
simply click & drag..etc
and study some article on : http://k79k06k02k.com/blog/542/unity/unity-ugui-%E5%8E%9F%E7%90%86%E7%AF%87%E4%BA%94%EF%BC%9Aauto-layout-%E8%87%AA%E5%8B%95%E4%BD%88%E5%B1%80
here is the first problem that I meet, the ScrollRect (ScrollView) within another ScrollRect will not pass the drag event to their parent(s)
well, it not a bug but I insist developer should able to easier design which event can bubble up to their parent.
for that reason I did some research on unity forum and realize the Event System limitation and behavior.
ref:
- https://docs.unity3d.com/ScriptReference/EventSystems.EventTrigger.html
- http://answers.unity3d.com/questions/902929/scroll-not-working-when-elements-inside-have-click.html
and created follow script to redirect the drag event to another specified ScrollRect (ScrollView)
UIDragPasser.cs
using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; namespace Kit.UI { [RequireComponent(typeof(ScrollRect))] public class UIDragPasser : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler { public ScrollRect m_Scroll; public ScrollRect m_OtherScroll; [Range(0f, 1f)] public float m_MinThrehold; [Range(0f, 1f)] public float m_MaxThrehold; private bool m_Allow = false; void OnValidate() { if (m_Scroll == null) m_Scroll = GetComponent<ScrollRect>(); if (m_OtherScroll == m_Scroll) m_OtherScroll = null; } public void OnBeginDrag(PointerEventData eventData) { m_Allow = IsAllow(eventData); if (m_Allow) { m_OtherScroll.OnBeginDrag(eventData); m_OtherScroll.SendMessage("OnBeginDrag", eventData, SendMessageOptions.DontRequireReceiver); } } public void OnDrag(PointerEventData eventData) { if (m_Allow) { m_OtherScroll.OnDrag(eventData); m_OtherScroll.SendMessage("OnDrag", eventData, SendMessageOptions.DontRequireReceiver); } } public void OnEndDrag(PointerEventData eventData) { if (m_Allow) { m_OtherScroll.OnEndDrag(eventData); m_OtherScroll.SendMessage("OnEndDrag", eventData, SendMessageOptions.DontRequireReceiver); } } private bool IsAllow(PointerEventData eventData) { if (!m_Scroll.vertical && !m_Scroll.horizontal) { return true; } else if (m_Scroll.horizontal) { return (Mathf.Abs(eventData.delta.y) > Mathf.Abs(eventData.delta.x)) || // Main direction (eventData.delta.x < 0f && m_Scroll.horizontalNormalizedPosition < m_MinThrehold) || // Left (eventData.delta.x > 0f && m_Scroll.horizontalNormalizedPosition > m_MaxThrehold); // Right } else // if (m_Scroll.vertical) { return (Mathf.Abs(eventData.delta.x) > Mathf.Abs(eventData.delta.y)) || // Main direction (eventData.delta.y > 0f && m_Scroll.verticalNormalizedPosition < m_MinThrehold) || // Bottom (eventData.delta.y < 0f && m_Scroll.verticalNormalizedPosition > m_MaxThrehold); // Top } } } }
by attach this script on ScrollRect (ScrollView) you can define which ScrollRect can receive the drag event
feature : when current Scroll are reaching the limit, the event should pass to its parents
as example 0.1f(Min) is bottom/left, 0.9f(Max) is top/right, well the direction was a little bit confuse me.
its not perfect, and still require developer to manually setup the UIDragPasser.cs, but at least we have a way to do it.
and then the result for apply this script.
and now I’m thinking about to implement the Infinitely loop content during scrolling Scrollview, any suggestion ?!
Study:
seem someone did it before~