策划需求: 滑动大的切页类型(横向)的同时,需滑动子切页中的物品(纵向),但是同一时间只会响应一个
以下代码可以实现这个需求,此需求设计的缺点是物品Item不能得到复用,因为横向切页的时候可以看到两个切页的物品,但是子ScrollView可以做一个循环列表的功能,有好的想法请在下方留言。
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEditor;
/// <summary>
/// 双重ScrollRect的水平移动与垂直移动叠加处理
/// 处理 同一时间 滑动父节点的ScrollRect 和 子节点的ScroollRect
/// 可以在此基础上再加下滑动的容错值
/// </summary>
public class VHScrollRect : ScrollRect
{
[HideInInspector]
public ScrollRect parentScroll;
[HideInInspector]
public bool isVertical = true;
private bool isSelf = false;
protected override void Awake()
{
parentScroll = transform.parent.parent.parent.GetComponent<ScrollRect>();
parentScroll.vertical = false;
isVertical = true;
}
public override void OnBeginDrag(PointerEventData eventData)
{
Vector2 touchDeltaPosition;
#if UNITY_EDITOR
float delta_x = Input.GetAxis("Mouse X");
float delta_y = Input.GetAxis("Mouse Y");
touchDeltaPosition = new Vector2(delta_x, delta_y);
#endif
#if !UNITY_EDITOR
touchDeltaPosition = Input.GetTouch(0).deltaPosition;
#endif
if (isVertical)
{
if (Mathf.Abs(touchDeltaPosition.x) < Mathf.Abs(touchDeltaPosition.y))
{
isSelf = true;
base.OnBeginDrag(eventData);
}
else
{
isSelf = false;
parentScroll.OnBeginDrag(eventData);
}
}
else
{
if (Mathf.Abs(touchDeltaPosition.x) > Mathf.Abs(touchDeltaPosition.y))
{
isSelf = true;
base.OnBeginDrag(eventData);
}
else
{
isSelf = false;
parentScroll.OnBeginDrag(eventData);
}
}
}
public override void OnDrag(PointerEventData eventData)
{
if (isSelf)
{
base.OnDrag(eventData);
}
else
{
parentScroll.OnDrag(eventData);
}
}
public override void OnEndDrag(PointerEventData eventData)
{
if (isSelf)
{
base.OnEndDrag(eventData);
}
else
{
parentScroll.OnEndDrag(eventData);
}
}
}
#if UNITY_EDITOR
[CustomEditor(typeof(VHScrollRect))]
[CanEditMultipleObjects]
public class VHScrollRectInspector : Editor
{
VHScrollRect mScrollRect;
SerializedProperty parentScrollRect;
private void OnEnable()
{
parentScrollRect = serializedObject.FindProperty("parentScroll");
mScrollRect = target as VHScrollRect;
}
public override void OnInspectorGUI()
{
base.OnInspectorGUI();
EditorGUILayout.LabelField("____________________________________________________________________");
serializedObject.Update();
EditorGUILayout.PropertyField(parentScrollRect, new GUIContent("父ScrollRect", "父ScrollRect,一定要指定"));
bool isVertical = EditorGUILayout.Toggle(new GUIContent("是否是垂直滑动", "是否是垂直滑动"), mScrollRect.isVertical);
if (mScrollRect.isVertical != isVertical)
{
mScrollRect.isVertical = isVertical;
EditorUtility.SetDirty(mScrollRect);
}
serializedObject.ApplyModifiedProperties();
}
}
#endif