Unity 实现多个RectTransform首尾无缝衔接无尽循环

文章介绍了Unity中的LoopMover脚本,它用于管理UI元素的循环移动,包括元素的初始化、动画设置、尺寸计算和无缝衔接。用户可以自定义每个元素的显示时间和大小,实现无尽循环效果。
摘要由CSDN通过智能技术生成
using System.Collections.Generic;
using DG.Tweening;
using UnityEngine;
/**
 * LoopMover类用于管理循环移动的UI元素。
 */
public class LoopMover : MonoBehaviour
{
    public List<RectTransform> items; // 存储需要循环移动的UI元素
    public List<RectTransform> images; // 存储与items对应的背景图片
    public float initWidth = 20f; // 初始化宽度
    public float startTime = 0; // 开始时间
    float cumulativeOffset = 0; // 累积偏移量

    public float[] times = new float[4]; // 每个元素显示的时间
    public float speed; // 移动速度
    /**
     * Awake函数在对象唤醒时调用,用于初始化图片大小和位置。
     */
    private void Awake()
    {
        if (images == null || images.Count == 0) return;

        speed = images[0].sizeDelta.x / times[0]; // 计算移动速度
        InitializeImageSizes(); // 初始化图片大小
        float totalx = 0;
        float totalWidth = GetTotalWidth(); // 计算总宽度
        // 设置每个元素的初始位置
        for (int i = items.Count - 1; i >= 0; i--)
        {
            RectTransform item = items[i];
            item.anchoredPosition = new Vector2(-(startTime * speed) + GetWidthWithoutImage(i), 0);
            // 调整元素位置以避免重叠
            if (item.anchoredPosition.x < 0 && item.anchoredPosition.x > -images[i].sizeDelta.x)
            {
                cumulativeOffset = item.anchoredPosition.x;
            }
            if (item.anchoredPosition.x <= -images[i].sizeDelta.x)
            {
                totalx += images[i].sizeDelta.x;
                item.anchoredPosition = new Vector2(totalWidth - totalx - Mathf.Abs(cumulativeOffset), 0);
            }
        }

    }

    /**
     * InitializeImageSizes函数用于设置每个背景图片的大小。
     */
    private void InitializeImageSizes()
    {
        for (int i = 0; i < images.Count; i++)
        {
            images[i].sizeDelta = new Vector2(times[i] * initWidth, 70); // 根据显示时间设置图片大小
        }
    }

    /**
     * Start函数在对象开始运行时调用,用于设置元素的动画效果。
     */
    void Start()
    {
        for (int i = 0; i < items.Count; i++)
        {
            RectTransform item = items[i];
            RectTransform image = images[i];
            int index = i;
            float newTime = (item.anchoredPosition.x + image.sizeDelta.x) / speed;
            // 设置元素移动到初始位置的动画,并在到达后循环移动
            item.DOAnchorPosX(-image.sizeDelta.x, newTime).SetEase((Ease.Linear)).OnComplete(() =>
            {
                item.anchoredPosition = new Vector2(GetWidth(index), 0);
                item.DOAnchorPosX(-image.sizeDelta.x, GetTime(items.Count)).SetEase((Ease.Linear)).SetLoops(-1);
            });
        }
    }

    /**
     * GetTotalWidth函数计算并返回所有背景图片的总宽度。
     *
     * @return float 所有背景图片的总宽度。
     */
    float GetTotalWidth()
    {
        float width = 0;
        for (int i = 0; i < images.Count; i++)
        {
            width += images[i].sizeDelta.x;
        }
        return width;
    }

    /**
     * GetWidth函数根据指定索引计算并返回除该索引对应元素外的所有元素宽度之和。
     *
     * @param idx 指定元素的索引。
     * @return float 除指定元素外的所有元素宽度之和。
     */
    float GetWidth(int idx)
    {
        float width = 0;
        for (int i = 0; i < images.Count; i++)
        {
            if (idx != i)
            {
                width += images[i].sizeDelta.x;
            }
        }
        return width;
    }

    /**
     * GetWidthWithoutImage函数根据指定索引计算并返回该索引之前的所有元素宽度之和。
     *
     * @param idx 指定元素的索引。
     * @return float 该索引之前的所有元素宽度之和。
     */
    float GetWidthWithoutImage(int idx)
    {
        float width = 0;
        for (int i = 0; i < images.Count; i++)
        {
            if (idx > i)
            {
                width += images[i].sizeDelta.x;
            }
        }
        return width;
    }

    /**
     * GetTime函数根据指定索引计算并返回该索引对应的时间。
     *
     * @param idx 指定元素的索引。
     * @return float 指定元素的显示时间。
     */
    float GetTime(int idx)
    {
        float time = 0;
        for (int i = 0; i < times.Length; i++)
        {
            if (i <= idx)
            {
                time += times[i];
            }
        }
        return time;
    }
}

实现多个RectTransform首尾无缝衔接无尽循环,可以通过自定义开始时间计算出当前开始的位置,支持每个RectTransform自定义大小。

资源下载

  • 9
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值