效果:
场景结构:
特殊物体:panel下面用排列组件horizent layout group放置多个需要显示的面板,用mask遮罩好。
主要思路:
这次是要在最后一个toggle的地方,依然向左滚动回1,这是难点。因此实际上在4后面,还增加了一个1面板的副本,等滑动到4后面的1后,直接重设整个panel的recttransform,狸猫换太子,视觉欺骗。
代码:
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);
}
}
}