因为项目须要+有网友咨询,因此作了个横向滑页+某一横向滑页中有竖向滑页的demo,实现有点绕弯子,但基本功能仍是比较完善,发上来共享一下。
第一步的思路是本身判断触屏拖动位置,而后控制界面横向或者纵向滑动。 而后, 因为UGUI组件重叠时会屏蔽事件 好比Button会屏蔽掉PointerDown (PS:固然也能够采起继承UGUI组件的方式释放屏蔽事件, 这里对UGUI源码不熟,采起本身写一个事件分发器方便一点)
这里就不赘述咯,个人前一篇blog有详细配置说明: 1.首先创建两个ScrollRect
2.分别给两个ScrollRect配置格子的ScrollBar,而后关掉如下设置
3.在最外层的ScrollRect配置ScrollControl代码 (PS:代码后续给出)
4.配置InputControl (PS:新建一个Gameobjct就能够咯,也能够挂在已有物体上)
5.运行,检查效果...
代码写的比较急,不少不规范的地方,使用者请看懂逻辑以后自行重构,直接使用者有坑勿怪
using UnityEngine; public delegate void MouseDownEvent(Vector2 mousePosition); public delegate void MouseUpEvent(Vector2 mousePosition); public delegate void MouseDragEvent(Vector2 dragVector); public delegate void MouseClickEvent(Vector2 mousePosition); public class InputControl : MonoBehaviour { private static InputControl mInstance; /// <summary> /// 逗比单例模式 /// </summary> public static InputControl Instance { get { return mInstance; } } private bool isPress; private bool isClick; private bool tempPress; private Vector2 oldMousePosition; private Vector2 tempMousePosition; public event MouseDownEvent EVENT_MOUSE_DOWN; public event MouseUpEvent EVENT_MOUSE_UP; public event MouseDragEvent EVENT_MOUSE_DRAG; public event MouseClickEvent EVENT_MOUSE_CLICK; /// <summary> /// 拖动起始判断参数,可自行更改 /// </summary> public const float JUDGE_DISTANCE = 1F; void Awake() { mInstance = this; //如下代码可优化 EVENT_MOUSE_DOWN += AvoidEmpty; EVENT_MOUSE_UP += AvoidEmpty; EVENT_MOUSE_DRAG += AvoidEmpty; EVENT_MOUSE_CLICK += AvoidEmpty; } void Start() { isPress = false; isClick = false; } /// <summary> /// 防空保护函数,无用处,可自行优化 /// </summary> /// <param name="noUse"></param> private void AvoidEmpty(Vector2 noUse) { } void Update() { tempPress = Input.GetMouseButton(0); tempMousePosition = Input.mousePosition; // 两次状态不一样,触发点击和抬起事件 if (tempPress != isPress) { // 按下事件 if (tempPress) { isClick = true; EVENT_MOUSE_DOWN(tempMousePosition); } // 抬起事件 else { EVENT_MOUSE_UP(tempMousePosition); // 点击事件 if (isClick) { EVENT_MOUSE_CLICK(tempMousePosition); } isClick = false; } } // 按下的过程当中发生了移动,发生事件变化 else if (isClick && JudgeMove(oldMousePosition, tempMousePosition)) { isClick = false; } // 拖动事件 else if (tempPress && !isClick) { EVENT_MOUSE_DRAG(tempMousePosition - oldMousePosition); } isPress = tempPress; oldMousePosition = tempMousePosition; } /// <summary> /// 判断是否超出静止范围,用static速度更快 /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <returns></returns> private static bool JudgeMove(Vector2 p1, Vector2 p2) { return Mathf.Abs(p1.x - p2.x) > JUDGE_DISTANCE || Mathf.Abs(p1.y - p2.y) > JUDGE_DISTANCE; } }
using UnityEngine; using UnityEngine.UI; public class ScrollControl : MonoBehaviour { /// <summary> /// 横向滚动条 /// </summary> public Scrollbar m_HScrollBar; /// <summary> /// 竖向滚动条 /// </summary> public Scrollbar[] m_VScrollBars; /// <summary> /// 有竖向滚动的页面 /// </summary> public int[] m_VScrollIndexs; /// <summary> /// 页面个数 /// </summary> public int m_Num; /// <summary> /// 设置移动超过多少百分比以后向下翻页 /// </summary> public float m_NextLimit; /// <summary> /// 滑动敏感值 /// </summary> public float m_Sensitive; /// <summary> /// 鼠标上一次的位置 /// </summary> private Vector3 mOldPosition; /// <summary> /// 记录上一次的value /// </summary> private float mOldValue; private float mTargetPosition = 0.5f; private int mCurrentIndex = 3; private int mTargetIndex = 3; /// <summary> /// 是否能够移动 /// </summary> private bool mCanMove = false; /// <summary> /// 初始移动速度 /// </summary> private float mMoveSpeed; /// <summary> /// 平滑移动参数 /// </summary> private const float SMOOTH_TIME = 0.2F; private float mDragParam = 0; private float mPageWidth = 0; /// <summary> /// 是否须要进行滑动方向断定 /// </summary> private bool mNeedCaculate = false; /// <summary> /// 是否进行竖向滚动 /// </summary> private bool mIsScollV = false; /// <summary> /// 竖向临时滚动条 /// </summary> private Scrollbar mVScrollBar; public void SetNextIndex(int pIndex) { mTargetIndex = pIndex; mTargetPosition = (mTargetIndex - 1) * mPageWidth; mIsScollV = false; mCanMove = true; } private void OnPointerDown(Vector2 mousePosition) { // 记录当前value mOldValue = m_HScrollBar.value; mOldPosition = Input.mousePosition; // mCanMove = false; mCurrentIndex = GetCurrentIndex(mOldValue); // 判断当前是否在可竖向滑动的页面上 for (int i = 0; i < m_VScrollIndexs.Length; ++i) { if (m_VScrollIndexs[i] == mCurrentIndex) { mNeedCaculate = true; mVScrollBar = m_VScrollBars[i]; break; } } } private void OnDrag(Vector2 mousePosition) { Vector2 dragVector = Input.mousePosition - mOldPosition; if (mNeedCaculate) { mNeedCaculate = false; if (Mathf.Abs(dragVector.x) > Mathf.Abs(dragVector.y)) { mIsScollV = false; } else { mIsScollV = true; } } DragScreen(dragVector); mOldPosition = Input.mousePosition; } private void OnPointerUp(Vector2 mousePosition) { Vector2 dragVector = Input.mousePosition - mOldPosition; DragScreen(dragVector); mOldPosition = Input.mousePosition; float valueOffset = m_HScrollBar.value - mOldValue; if (Mathf.Abs((valueOffset) / mPageWidth) > m_NextLimit) { mTargetIndex += valueOffset > 0 ? 1 : -1; mTargetPosition = (mTargetIndex - 1) * mPageWidth; } mCanMove = true; } private int GetCurrentIndex(float pCurrentValue) { return Mathf.RoundToInt(pCurrentValue / mPageWidth + 1); } private void DragScreen(Vector2 pDragVector) { if (mIsScollV) { float oldValue = mVScrollBar.value; mVScrollBar.value -= pDragVector.y / Screen.height * mVScrollBar.size; mMoveSpeed = mVScrollBar.value - oldValue; } else { float oldValue = m_HScrollBar.value; m_HScrollBar.value -= pDragVector.x / Screen.width * mDragParam; mMoveSpeed = m_HScrollBar.value - oldValue; } } void Awake() { if (m_Num <= 1) { Debug.LogError("参数错误:页面个数不对"); } mDragParam = 1f / (m_Num - 1) * m_Sensitive; mPageWidth = 1f / (m_Num - 1); mCurrentIndex = GetCurrentIndex(m_HScrollBar.value); mTargetIndex = mCurrentIndex; } void Start() { InputControl.Instance.EVENT_MOUSE_DOWN += OnPointerDown; InputControl.Instance.EVENT_MOUSE_UP += OnPointerUp; InputControl.Instance.EVENT_MOUSE_DRAG += OnDrag; } void OnDestory() { InputControl.Instance.EVENT_MOUSE_DOWN -= OnPointerDown; InputControl.Instance.EVENT_MOUSE_UP -= OnPointerUp; InputControl.Instance.EVENT_MOUSE_DRAG -= OnDrag; } void Update() { if (mCanMove) { if (mIsScollV) { mVScrollBar.value += mMoveSpeed; float absValue = Mathf.Abs(mMoveSpeed); absValue -= 0.001f; if (absValue <= 0) { mCanMove = false; } else { mMoveSpeed = mMoveSpeed > 0 ? absValue : -absValue; } } else { if (Mathf.Abs(m_HScrollBar.value - mTargetPosition) < 0.01f) { m_HScrollBar.value = mTargetPosition; mCurrentIndex = mTargetIndex; mCanMove = false; return; } m_HScrollBar.value = Mathf.SmoothDamp(m_HScrollBar.value, mTargetPosition, ref mMoveSpeed, SMOOTH_TIME); } } } }
目前来看效果还能够,两种滑动无干扰,有简单的阻尼滑动效果,滑动分页界限能够设置 其余如有什么问题,欢迎留言