Unity实现UI图片面板滚动播放效果第二弹

效果:

场景结构:

特殊物体:panel下面用排列组件horizent layout group放置多个需要显示的面板,用mask遮罩好。

主要思路:

这次是要在最后一个toggle的地方,依然向左滚动回1,这是难点。因此实际上在4后面,还增加了一个1面板的副本,等滑动到4后面的1后,直接重设整个panel的recttransform,狸猫换太子,视觉欺骗。

代码:

cs 复制代码
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using DG.Tweening;
using UnityEngine;
using UnityEngine.UI;

public class RollControlPanel : MonoBehaviour
{
    private RectTransform rollPanel;
    private Vector2 startPos;

    private ToggleGroup toggleGroup;

    private Toggle[] toggles;

    private int preToggleIndex = 0;
    private int curToggleIndex = 0;

    private int toggleCount;

    public float moveValue = 756;
    private Tween slideTween;
    private List<Vector2> panelPos = new List<Vector2>();
    
    // Start is called before the first frame update
    void Start()
    {
        rollPanel = transform.Find("Mask/RollPanel").GetComponent<RectTransform>();
        toggleGroup = transform.Find("TogglePanel/ToggleGroup").GetComponent<ToggleGroup>();
        toggles = transform.GetComponentsInChildren<Toggle>();

        startPos = rollPanel.anchoredPosition;
        panelPos.Add(startPos);

        int panelCount = rollPanel.childCount;
        for (int i = 1; i < panelCount; i++)
        {
            Vector2 tmp = new Vector2(startPos.x - i * moveValue, startPos.y);
            panelPos.Add(tmp);
        }
        
        toggleCount = toggles.Length;
        for (int i = 0; i < toggleCount; i++)
        {
            Toggle toggle = toggles[i];
            toggles[i].onValueChanged.AddListener((arg0 =>
            {
                OnToggleOpen(toggle);
            }));
        }

        IEnumerator enumerator = MovePanel();
        Coroutine setTogglesetToggle= StartCoroutine(enumerator);
    }
    
    /// <summary>
    /// 只关注循环播放
    /// </summary>
    /// <returns></returns>
    IEnumerator MovePanel()
    {
        while (true)
        {
            yield return new WaitForSeconds(2f);
            if (curToggleIndex==toggleCount-1)
            {
                //挪到最后一个(也就是第一个的副本),偷偷重置位置
                slideTween = rollPanel.DOAnchorPosX(panelPos[panelPos.Count - 1].x, 0.5f).OnComplete((() =>
                {
                    rollPanel.anchoredPosition = startPos;
                }));
                
                for (int i = 0; i < toggleCount; i++)
                {
                    toggles[i].onValueChanged.RemoveAllListeners();
                }
                toggles[0].isOn = true;
                for (int i = 0; i < toggleCount; i++)
                {
                    Toggle toggle = toggles[i];
                    toggles[i].onValueChanged.AddListener((arg0 =>
                    {
                        OnToggleOpen(toggle);
                    }));
                }

                preToggleIndex = curToggleIndex;
                curToggleIndex = 0;
                
            }
            else
            {
                //正常相对于当前位置移动
                curToggleIndex++;
                slideTween = rollPanel.DOAnchorPosX(panelPos[curToggleIndex].x, 0.5f);
                
                for (int i = 0; i < toggleCount; i++)
                {
                    toggles[i].onValueChanged.RemoveAllListeners();
                }
                toggles[curToggleIndex].isOn = true;
                for (int i = 0; i < toggleCount; i++)
                {
                    Toggle toggle = toggles[i];
                    toggles[i].onValueChanged.AddListener((arg0 =>
                    {
                        OnToggleOpen(toggle);
                    }));
                }
                
                preToggleIndex = curToggleIndex;
            }
        }
    }

    // private void Update()
    // {
    //     if (Input.GetKeyDown(KeyCode.K))
    //     {
    //         StopAllCoroutines();
    //         slideTween.Kill();
    //         rollPanel.anchoredPosition = startPos;
    //     }
    // }

    void OnToggleOpen(Toggle toggle)
    {
        StopAllCoroutines();
        slideTween.Kill();

        if (toggle.isOn)
        {
            for (int i = 0; i < toggleCount; i++)
            {
                if (toggle == toggles[i])
                {
                    curToggleIndex = i;
                    break;
                }
            }
            
            //直接切换rect位置
            rollPanel.anchoredPosition = panelPos[curToggleIndex];
            
            IEnumerator enumerator = MovePanel();
            Coroutine setTogglesetToggle= StartCoroutine(enumerator);


        }
    }
}
相关推荐
久爱物联网12 分钟前
【WinForm UI控件系列】Battery 电池电量控件
ui·winformui控件·桌面应用控件·c#控件ui·ui控件gdi
ZC跨境爬虫30 分钟前
UI前端美化技能提升日志day5:从布局优化到CSS继承原理深度解析
前端·css·ui·html·状态模式
LF男男37 分钟前
MK - Grand Mahjong Game-
unity·c#
呆呆敲代码的小Y1 小时前
【Unity实战篇】| YooAsset + UOS CDN 云服务资源部署,实现正式热更流程
人工智能·游戏·unity·游戏引擎·免费游戏
久爱物联网1 小时前
【WinForm UI控件系列】AlarmLight 报警灯\声光报警灯控件
ui·winformui控件·桌面应用控件·c# ui控件·gdi控件 net控件
WarPigs1 小时前
unity多语言框架
unity
代数狂人1 小时前
《深入浅出Godot 4与C# 3D游戏开发》第一章:了解Godot与搭建开发环境
c#·游戏引擎·godot
RReality2 小时前
【UGUI】自定义 ListView 架构:设计、原理与可扩展性
unity·架构
Wenzar_2 小时前
# 发散创新:SwiftUI 中状态管理的深度实践与重构艺术 在 SwiftUI 的世界里,**状态驱动 UI 是核心哲学**。但随
java·python·ui·重构·swiftui
Ulyanov2 小时前
《PySide6 GUI开发指南:QML核心与实践》 第五篇:Python与QML深度融合——数据绑定与交互
开发语言·python·qt·ui·交互·雷达电子战系统仿真