Rolling cycle

using System;
using System.Collections.Generic;
using UnityEngine.EventSystems;

namespace UnityEngine.UI
{
    public class LoopScroll : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler
    {
        public enum DragMode
        {
            None,
            Horizontal,
            Vertical,
        }

        public Action<int> callBack;

        public DragMode mode;

        public Transform content;

        [Tooltip("拖拽速度"), The Range ( . 1 , 100F)]
         public  a float Speed = . 1 ; 

        [Tooltip ( " middle speed " ), the Range ( . 1 , 20f)]
         public  a float ratio = . 1 ; 

        [Tooltip ( " slide intensity " ), the Range ( 10 , 1000 )]
         public  a float Spring = 30 ; 

        [Tooltip ( " Auto Show " )]
         public  BOOL Auto; 

        [Tooltip ( " display interval (s)"), Range(1, 60)]
        public float interval = 3;

        [HideInInspector]
        public bool lockDrag;

        public Vector2 center;

        private Vector2 space;

        private Vector2 cell;

        private Vector2 vector;

        private float offset;

        private Vector2 position;

        private Vector2 point_begin;

        private Vector2 point_end;

        private int index_pre;

        private int index_target;

        private float spring_value;

        private int spring_offset;

        private bool center_state;

        private float center_ratio;

        private Vector2 center_vector;

        private Vector2 center_position;

        private float auto_timer;

        private bool m_drag;

        private readonly List<RectTransform> m_childs = new List<RectTransform>();

        private void Awake()
        {
            FormatPosition();
        }

        private void Update()
        {
            if (!m_drag && center_state)
            {
                center_ratio += Time.deltaTime * ratio;
                center_position = Vector2.Lerp(m_childs[index_target].localPosition, center, center_ratio);
                center_vector = center_position - (Vector2)m_childs[index_target].localPosition;

                Drag(center_vector);

                if (center_ratio > 1)
                {
                    center_state = false;
                }
            }

            if (auto)
            {
                if (m_drag)
                    auto_timer = 0;
                else
                    auto_timer += Time.deltaTime;

                if (auto_timer >= interval)
                {
                    auto_timer = 0;

                    Next();
                }
            }
        }

        public void OnBeginDrag(PointerEventData eventData)
        {
            if (lockDrag) return;

            point_begin = Input.mousePosition;

            m_drag = true;
        }

        public void OnDrag(PointerEventData eventData)
        {
            if (m_drag)
            {
                Drag(eventData.delta * speed * Time.deltaTime);
            }
        }

        public void OnEndDrag(PointerEventData eventData)
        {
            if (lockDrag) return;

            point_end = Input.mousePosition;

            m_drag = false;

            index_target = -1;

            for (int i = 0; i < m_childs.Count; i++)
            {
                if (Center(m_childs[i].localPosition))
                {
                    index_target = i;
                    break;
                }
            }

            if (index_target != -1)
            {
                if (index_target == index_pre)
                {
                    switch (mode)
                    {
                        case DragMode.Horizontal:
                            spring_value = point_end.x - point_begin.x;
                            break;
                        case DragMode.Vertical:
                            spring_value = point_end.y - point_begin.y;
                            break;
                    }

                    if (Math.Abs(spring_value) > spring)
                    {
                        spring_offset = spring_value > 0 ? -1 : 1;

                        index_target += spring_offset;

                        if (index_target < 0)
                        {
                            index_target += m_childs.Count;
                        }
                        else if (index_target >= m_childs.Count)
                        {
                            index_target %= m_childs.Count;
                        }
                    }
                }

                index_pre = index_target;

                callBack?.Invoke(index_target);
            }

            center_ratio = 0;
            center_state = index_target != -1;
        }

        public void FormatPosition()
        {
            m_childs.Clear();

            Content _content = content.GetComponent<Content>();
            cell.x = _content.Horiaontal;
            cell.y = _content.Vertical;

            for (int i = 0; i < content.childCount; i++)
            {
                if (content.GetChild(i).gameObject.activeSelf)
                {
                    m_childs.Add(content.GetChild(i) as RectTransform);
                }
            }

            Vector2 _position = center;

            for (int i = 0; i < m_childs.Count; i++)
            {
                m_childs[i].anchorMin = Vector2.one * 0.5f;
                m_childs[i].anchorMax = Vector2.one * 0.5f;
                m_childs[i].pivot = Vector2.one * 0.5f;
                m_childs[i].anchoredPosition = _position;

                switch (mode)
                {
                    case DragMode.Horizontal:
                        _position.x += cell.x;
                        break;
                    case DragMode.Vertical:
                        _position.y -= cell.y;
                        break;
                    default:
                        _position += cell;
                        break;
                }
            }

            int preview_index = 2;

            if (m_childs.Count > 0)
            {
                switch (mode)
                {
                    case DragMode.Horizontal:
                        space.x = m_childs[0].localPosition.x - preview_index * cell.x;
                        space.y = m_childs[m_childs.Count - preview_index].localPosition.x;
                        break;
                    case DragMode.Vertical:
                        space.x = m_childs[m_childs.Count - preview_index].localPosition.y;
                        space.y = m_childs[0].localPosition.y + preview_index * cell.y;
                        break;
                }
            }
            else
            {
                space = Vector2.zero;
            }
        }

        public void Jump(int index)
        {
            index_pre = index_target = index;

            if (index_target != -1)
            {
                callBack?.Invoke(index_target);
            }

            center_ratio = 0;
            center_state = index_target != -1;
        }

        private void Next()
        {
            index_target++;

            if (index_target >= m_childs.Count)
            {
                index_target %= m_childs.Count;
            }
            index_pre = index_target;

            Drag(Vector2.one * -1);

            if (index_target != -1)
            {
                callBack?.Invoke(index_target);
            }

            center_ratio = 0;
            center_state = index_target != -1;
        }

        private void Drag(Vector2 delta)
        {
            switch (mode)
            {
                case DragMode.Horizontal:
                    vector.x = delta.x;
                    vector.y = 0;
                    break;
                case DragMode.Vertical:
                    vector.x = 0;
                    vector.y = delta.y;
                    break;
                default:
                    vector = delta;
                    break;
            }

            for (int i = 0; i < m_childs.Count; i++)
            {
                position = m_childs[i].localPosition;
                position += vector;

                switch (mode)
                {
                    case DragMode.Horizontal:
                        if (position.x > space.y)
                        {
                            offset = position.x - space.y;
                            position.x = space.x + offset;
                        }
                        else if (position.x < space.x)
                        {
                            offset = position.x - space.x;
                            position.x = space.y + offset;
                        }
                        break;
                    case DragMode.Vertical:
                        if (position.y > space.y)
                        {
                            offset = position.y - space.y;
                            position.y = space.x + offset;
                        }
                        else if (position.y < space.x)
                        {
                            offset = position.y - space.x;
                            position.y = space.y + offset;
                        }
                        break;
                    default:
                        break;
                }

                m_childs[i].localPosition = position;
            }
        }

        private bool Center(Vector2 position)
        {
            bool result = false;

            switch (mode)
            {
                case DragMode.Horizontal:
                    result = Math.Abs(position.x - center.x) < cell.x / 2;
                    break;
                case DragMode.Vertical:
                    result = Math.Abs(position.y - center.y) < cell.y / 2;
                    break;
            }

            return result;
        }
    }
}
View Code

A minimum of three sub-objects, if less than three clones can be processed.

After calling FormatPosition code generated subobject End ();

Guess you like

Origin www.cnblogs.com/Joke-crazy/p/12582059.html