Implement slide page nesting in Unity (solving ScrollRect nesting conflicts)
Introduction
As the project needs to be consulted by more users, a horizontal slide page + a horizontal slide page with a vertical slide page demo is provided to achieve a little detour, but the basic functions are still relatively complete, share it.
Effect
Ideas
The first step is to determine the drag position of the touch screen and then control the horizontal or vertical sliding of the interface. Then, because UGUI components overlap, events will be blocked. For example, the Button will block the PointerDown (PS: Of course, you can also release the blocking events by inheriting the UGUI components. Here, the UGUI source code is not familiar, it is easier to write an event distributor by yourself)
Project Configuration
I will not go into details here. My previous blog has detailed configuration instructions: 1. First, we will create two ScrollRect
2. Configure the ScrollBar of the grid for the two ScrollRect instances, and disable the following settings.
3. Configure the ScrollControl code in the outermost ScrollRect (PS: code will be provided later)
4. Configure InputControl (PS: You can create a new Gameobjct, or you can mount it on an existing object)
5. Run and check the results...
Code
Code writing is urgent, and many non-standard places. users need to understand the logic and then refactor it themselves.
InputControl
Using UnityEngine; public delegate void Merge (Vector2 mousePosition); public delegate void Merge (Vector2 mousePosition); public delegate void MouseDragEvent (Vector2 dragVector); public delegate void MouseClickEvent (Vector2 mousePosition ); public class InputControl: MonoBehaviour {private static InputControl mInstance ;////// Compared to singleton mode ///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 ;////// Drag the start judgment parameter, which can be changed by yourself ///Public const float identifier = 1F; void Awake () {mInstance = this; // the following code optimizes EVENT_MOUSE_DOWN + = AvoidEmpty; EVENT_MOUSE_UP + = AvoidEmpty; EVENT_MOUSE_DRAG + = AvoidEmpty; EVENT_MOUSE_CLICK + = AvoidEmpty;} void Start () {isPress = false; isClick = false ;}////// The anti-DDoS function. It is useless and can be optimized by yourself //////Private void AvoidEmpty (Vector2 noUse) {} void Update () {tempPress = Input. getMouseButton (0); tempMousePosition = Input. mousePosition; // The two statuses are different. if (tempPress! = IsPress) {// press event if (tempPress) {isClick = true; EVENT_MOUSE_DOWN (tempMousePosition);} // lift event else {EVENT_MOUSE_UP (tempMousePosition ); // The click event if (isClick) {EVENT_MOUSE_CLICK (tempMousePosition) ;}isclick = false ;}// a movement occurred during the press, event change else if (isClick & JudgeMove (oldMousePosition, tempMousePosition) {isClick = false ;}// drag the event else if (tempPress &&! IsClick) {EVENT_MOUSE_DRAG (tempMousePosition-oldMousePosition);} isPress = tempPress; oldMousePosition = tempMousePosition ;}////// Determine whether the static range is exceeded and the static speed is faster ////////////
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 ;}}
ScrollControl
Using UnityEngine; using UnityEngine. UI; public class ScrollControl: MonoBehaviour {////// Horizontal scroll bar ///Public Scrollbar m_HScrollBar ;////// Vertical scroll bar ///Public Scrollbar [] m_VScrollBars ;////// Page with vertical scrolling ///Public int [] m_VScrollIndexs ;////// Page count ///Public int m_Num ;////// Set the percentage of movement that exceeds the limit and flip the page down ///Public float m_NextLimit ;////// Sliding sensitive value ///Public float m_Sensitive ;////// The last cursor position ///Private Vector3 mOldPosition ;////// Record the last value ///Private float mOldValue; private float mTargetPosition = 0.5f; private int mCurrentIndex = 3; private int mTargetIndex = 3 ;////// Whether it can be moved ///Private bool mCanMove = false ;////// Initial moving speed ///Private float mMoveSpeed ;////// Smooth moving parameters ///Private const float SMOOTH_TIME = 0.2F; private float mDragParam = 0; private float mPageWidth = 0 ;////// Determine the moving direction ///Private bool mNeedCaculate = false ;////// Do You Want To scroll vertically ///Private bool mIsScollV = false ;////// Vertical temporary scroll bar ///Private Scrollbar mVScrollBar; public void SetNextIndex (int pIndex) {mTargetIndex = pIndex; mTargetPosition = (mTargetIndex-1) * mPageWidth; mIsScollV = false; mCanMove = true ;} private void OnPointerDown (Vector2 mousePosition) {// record the current value mOldValue = m_HScrollBar.value; mOldPosition = Input. mousePosition; // mCanMove = false; mCurrentIndex = GetCurrentIndex (mOldValue); // you can determine whether the current position is on a page that can be swiped vertically. Or (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-oldVal Ue;} 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 ("parameter error: Incorrect page count");} 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) {mVS CrollBar. 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 );}}}}