UGUI轮播1.1.0

做了部分优化及功能添加

效果:

下载链接

 

/*******************************************************************************
* 版本声明:v1.1.0
* 类 名 称:UIRotationManager
* 创建日期:2020-05-19 15:52:49
* 作者名称:末零
* 功能描述:UGUI轮播
* 修改记录:
*           v1.0.0   完成左右一位的位移(暂时不支持多位移动)
*           v1.0.1   优化排列时位置的计算,解决遮盖问题
*           v1.0.2   解决SiblingIndex设置后出现外侧遮盖内侧的问题
*           v1.1.0   添加显示数量控制
*           
******************************************************************************/

using System.Collections.Generic;
using UnityEngine;

using DG.Tweening;

namespace LastZero
{
    /// <summary>
    /// 状态枚举
    /// </summary>
    public enum RotationState
    {
        Rotating,
        Stop
    }

    /// <summary>
    /// 轮播
    /// </summary>
    public class UIRotationManager : MonoBehaviour
    {
        public int indexCenter = 0;//初始时,位于中间位置的对象ID
        public float cellWidth = 100;//宽度
        public float scaleMultiple = 1;//缩放倍数
        public float speed = 5;//轮播速度
        public int displayNumber = 0;//要显示的轮播物体个数

        private List<UIRotationItem> items = new List<UIRotationItem>();//所有子物体(要轮播的)
        private List<int> relativePosition = new List<int>();//相对位置

        private int indexHalf;//轮播对象数量的中值
        private List<int> order = new List<int>();//顺序
        private RotationState state = RotationState.Stop;//状态

        private void Awake()
        {
            items.AddRange(transform.GetComponentsInChildren<UIRotationItem>());
        }

        private void Start()
        {
            Init();
        }

        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.LeftArrow))
            {
                DoRotateItems(1);
            }
            if (Input.GetKeyDown(KeyCode.RightArrow))
            {
                DoRotateItems(-1);
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void Init()
        {
            displayNumber = displayNumber == 0 ? items.Count : displayNumber;

            indexHalf = (items.Count - 1) / 2;

            for (int i = 0; i < items.Count; i++)
            {
                int target = i - indexHalf + indexCenter;
                target = target < 0 ? target + items.Count : target >= items.Count ? target - items.Count : target;
                items[i] = transform.GetChild(target).GetComponent<UIRotationItem>();

                relativePosition.Add(i - indexHalf);
            }

            DoRotateItems();
        }

        /// <summary>
        /// 获取当前状态
        /// </summary>
        /// <returns></returns>
        public RotationState GetState()
        {
            return state;
        }

        /// <summary>
        /// 轮播
        /// </summary>
        /// <param name="value"></param>
        public void DoRotateItems(int value = 0)
        {
            if (state == RotationState.Rotating) return;
            
            order.Clear();

            for (int i = 0; i < items.Count; i++)
            {
                int target = i + value;

                if (target < 0)
                {
                    target += items.Count;
                }
                else if (target >= items.Count)
                {
                    target -= items.Count;
                }
                order.Add(target);

                float positionX = 0f;
                for (int j = 1; j <= Mathf.Abs(relativePosition[target]); j++)
                {
                    positionX += cellWidth * Mathf.Pow(scaleMultiple, j) * (relativePosition[target] == 0 ? 0 : Mathf.Abs(relativePosition[target]) / relativePosition[target]);
                }

                //            一半的位置 - 要显示个个数的一半 -> 左侧               半数      + 要显示的个数减去左侧已显示的
                if((target < (indexHalf - (displayNumber - 1) / 2)) || target > (indexHalf + displayNumber - (displayNumber - 1) / 2 - 1))//隐藏掉左右两端不该显示的
                {
                    items[i].LocalScale = 0;
                }
                else if ((target == (indexHalf - (displayNumber - 1) / 2) && value > 0) || (target == (indexHalf + displayNumber - (displayNumber - 1) / 2 - 1) && value < 0))
                {
                    int indexI = i;
                    int indexTarget = target;
                    items[i].transform.DOScale(0.01f, Mathf.Abs(value) / speed * 0.5f).OnComplete(() =>
                    {
                        items[indexI].LocalPositionX = positionX;//relativePosition[indexTarget] * cellWidth * Mathf.Pow(scaleMultiple, Mathf.Abs(relativePosition[indexTarget]));
                        items[indexI].transform.DOScale(Mathf.Pow(scaleMultiple, Mathf.Abs(relativePosition[indexTarget])), Mathf.Abs(value) / speed * 0.5f).SetEase(Ease.Linear);
                    });
                }
                else
                {
                    items[i].transform.DOLocalMoveX(positionX, Mathf.Abs(value) / speed).SetEase(Ease.Linear);
                    items[i].transform.DOScale(Mathf.Pow(scaleMultiple, Mathf.Abs(relativePosition[target])), Mathf.Abs(value) / speed).OnComplete(() =>
                    {
                        state = RotationState.Stop;
                    }).SetEase(Ease.Linear);
                }  
            }
            StartCoroutine(CallBack(Mathf.Abs(value)));
            state = RotationState.Rotating;
        }

        /// <summary>
        /// 回调(单次轮播进行到一半时,重置List、改变SiblingIndex)
        /// </summary>
        /// <param name="time"></param>
        /// <returns></returns>
        private System.Collections.IEnumerator CallBack(int time)
        {
            yield return new WaitForSeconds(time * 0.5f / speed);

            UIRotationItem[] newItems = new UIRotationItem[items.Count];
            for (int i = 0; i < items.Count; i++)
            {
                newItems[order[i]] = items[i];
            }
            items.Clear();
            items.AddRange(newItems);
            ChangeSiblingIndex();
        }

        /// <summary>
        /// 改变SiblingIndex
        /// </summary>
        private void ChangeSiblingIndex()
        {
            for (int i = 0; i < items.Count; i++)
            {
                int index;
                index = relativePosition[i] > 0 ? items.Count - 1 - relativePosition[i] * 2 + 1 : items.Count - 1 + relativePosition[i] * 2;
                
                items[i].SiblingIndex = index;
            }
        }
    }
}

 

评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

末零

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值