同时滑动父节点的ScrollRect和子节点的ScroollRect

策划需求: 滑动大的切页类型(横向)的同时,需滑动子切页中的物品(纵向),但是同一时间只会响应一个
以下代码可以实现这个需求,此需求设计的缺点是物品Item不能得到复用,因为横向切页的时候可以看到两个切页的物品,但是子ScrollView可以做一个循环列表的功能,有好的想法请在下方留言。

using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEditor;

/// 
/// 双重ScrollRect的水平移动与垂直移动叠加处理
/// 处理 同一时间 滑动父节点的ScrollRect 和 子节点的ScroollRect
/// 可以在此基础上再加下滑动的容错值
/// 
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

你可能感兴趣的:(Unity3D)