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);


        }
    }
}
相关推荐
Devlab11 小时前
LVGL设计大师——网页版anyui来了!!
嵌入式硬件·物联网·低代码·ui·iot
_ZHOURUI_H_19 小时前
Unity TCP底层极限拆解:粘包、半包、CRC、序列号、双缓冲到底怎么一起工作的?
网络·网络协议·tcp/ip·游戏·unity·游戏引擎·游戏开发
向星而行_star1 天前
Ito 模型在业务场景中的落地应用指南
ui
KindSuper_liu1 天前
Unity 游戏网络基础:从 TCP、UDP 到 HTTP、TLS 与 Best HTTP
网络·游戏·unity
界面开发小八哥1 天前
界面控件DevExpress XAF v26.1新版亮点——Blazor UI功能增强(二)
ui·界面控件·blazor·devexpress·ui开发
qq_170264751 天前
unity里GameObject和Texture的内存归属
java·unity·游戏引擎
Oll Correct1 天前
Adobe illustrator 案例四:吃豆人 (Pac-Man)图标绘制
笔记·ui·adobe·illustrator
weixin_404679311 天前
godot + vscode ai开发
ide·vscode·编辑器·游戏引擎·godot
阿图灵2 天前
Agentic AI 架构入门(九):Agent 通信协议全景——ACP/A2A/AG-UI/MCP
人工智能·ui·架构·ai agent·智能体·mcp·agentic ai
还是大剑师兰特2 天前
Unity3D(Unity)完整详细介绍
unity·游戏引擎