Unity DOTween 实现UGUI 轮播效果

文章讲述了在Unity中实现一个动态按钮轮播效果,通过Vector3记录按钮位置,根据按钮总数调整显示和隐藏策略,使用DOLocalMove和DOScale进行平滑移动和缩放。涉及了三种情况:三个按钮、三个以上按钮的处理方式和停止轮播的逻辑。
摘要由CSDN通过智能技术生成

效果

三个按钮

多于三个按钮 

实现 

图片遮罩实现按钮显示或隐藏,Vector3 记录遮罩左右两侧和遮罩内左到右三个按钮的位置,移动至遮罩内则显示,移动至遮罩左右两侧则隐藏。用List 存储所有按钮,以下标为索引获取指定按钮;以中间按钮的Scale 为标准大小按固定倍率缩小左右按钮;DOLocalMove 和DOScale 实现最终轮播效果。

显示

显示按钮时需要考虑到按钮总数量。

按钮总数量小于遮罩内显示的按钮数量时只需直接显示。

按钮总数量大于等于遮罩内显示的按钮数量时,索引顺序前三个按钮在遮罩内从左至右显示,其它按钮移动至遮罩右侧。

按钮总数量小于3

if (transBtns.Count == 1)
{
    transBtns[expIndexLeft].localPosition = posBtnsShow[1];
}
else if (transBtns.Count == 2)
{
    transBtns[expIndexLeft].localPosition = posBtnsShow[0];
    transBtns[expIndexMiddle].localPosition = posBtnsShow[2];
}


foreach (var item in transBtns)
{
    item.localScale = scaleBtnMiddle;
    item.Find("EffectImage").gameObject.SetActive(false);
}

按钮总数量大于等于3

foreach (var item in transBtns)
{
    item.localPosition = posRightHide;
    item.localScale = scaleBtnMiddle / Mathf.Pow(rateScale, 2);
    item.Find("EffectImage").gameObject.SetActive(false);
}
transBtns[expIndexLeft].localPosition = posBtnsShow[0];
transBtns[expIndexLeft].localScale = scaleBtnMiddle / rateScale;
transBtns[expIndexMiddle].localPosition = posBtnsShow[1];
transBtns[expIndexMiddle].localScale = scaleBtnMiddle;
transBtns[expIndexMiddle].Find("EffectImage").gameObject.SetActive(true);
transBtns[expIndexRight].localPosition = posBtnsShow[2];
transBtns[expIndexRight].localScale = scaleBtnMiddle / rateScale;

轮播 (以左侧按钮移向中间为例)

轮播效果按按钮数量分三个按钮和三个以上按钮两种情况。

按钮总数为三个时,三个按钮在遮罩内移动。

按钮总数大于三个时除开遮罩内三个可见按钮,其余按钮都移动至遮罩左右两侧。

轮播的实现以预期的遮罩内显示的三个按钮在List 里的索引为主导。

三个按钮

只有三个按钮时只需要确定每个按钮的位置后移动对应按钮。

确定预期按钮和索引
expIndexLeft = indexLeftCurrent - 1 >= 0 ? indexLeftCurrent - 1 : transBtns.Count - 1;
expIndexMiddle = expIndexLeft + 1 < transBtns.Count ? expIndexLeft + 1 : 0;
expIndexRight = expIndexMiddle + 1 < transBtns.Count ? expIndexMiddle + 1 : 0;

Transform transExpLeft = transBtns[expIndexLeft];
transExpLeft.SetAsFirstSibling();
Transform transExpMiddle = transBtns[expIndexMiddle];
Transform transExpRight = transBtns[expIndexRight];
transExpRight.SetAsLastSibling();
移动
transExpLeft.DOLocalMove(posBtnsShow[0], 1);
transExpLeft.DOScale(scaleBtnMiddle / Mathf.Pow(rateScale, 2), 0.3f).onComplete += () =>
{
    transExpLeft.DOScale(scaleBtnMiddle / rateScale, 0.4f);
};

transExpMiddle.Find("EffectImage").gameObject.SetActive(true);
transExpMiddle.DOLocalMove(posBtnsShow[1], 1);
transExpMiddle.DOScale(scaleBtnMiddle, 0.8f);

transExpRight.Find("EffectImage").gameObject.SetActive(false);
transExpRight.DOLocalMove(posBtnsShow[2], 1);
transExpRight.DOScale(scaleBtnMiddle / rateScale, 0.8f);

多于三个按钮

按钮总数多于三个时,除去将要显示的按钮移动至对应位置,还需要隐藏最右侧的按钮。

确定预期按钮和索引
indexBtnNeedHide = indexLeftCurrent + 2 < transBtns.Count ? indexLeftCurrent + 2 : indexLeftCurrent + 2 - transBtns.Count;
移动 
transExpLeft.localPosition = posLeftHide;
transExpLeft.localScale = scaleBtnMiddle / Mathf.Pow(rateScale, 2);
transExpLeft.DOLocalMove(posBtnsShow[0], 1);
transExpLeft.DOScale(scaleBtnMiddle / rateScale, 0.8f);

transExpMiddle.Find("EffectImage").gameObject.SetActive(true);
transExpMiddle.DOLocalMove(posBtnsShow[1], 1);
transExpMiddle.DOScale(scaleBtnMiddle, 0.8f);

transExpRight.Find("EffectImage").gameObject.SetActive(false);
transExpRight.DOLocalMove(posBtnsShow[2], 1);
transExpRight.DOScale(scaleBtnMiddle / rateScale, 0.8f);

transBtns[indexBtnNeedHide].DOLocalMove(posRightHide, 1);
transBtns[indexBtnNeedHide].DOScale(scaleBtnMiddle / Mathf.Pow(rateScale, 2), 0.8f);

停止轮播

每一次从开始移动到结束都需要一定时间,意味着在移动时再执行一次移动就容易出现问题,因此需要在每次开始移动前停止上一次移动。

DOTween.KillAll();

停止移动后需设定按钮位置和大小,可利用预期索引和当前索引判断上一次移动方向,从而确定每个按钮的位置和大小。

int indexBtnNeedHide;
Vector3 posHide;
if (expIndexLeft <= indexLeftCurrent)
{
    indexBtnNeedHide = indexLeftCurrent + 2 < transBtns.Count ? indexLeftCurrent + 2 : indexLeftCurrent + 2 - transBtns.Count;
    posHide = posRightHide;
}
else
{
    indexBtnNeedHide = indexLeftCurrent;
    posHide = posLeftHide;
}
expIndexMiddle = expIndexLeft + 1 < transBtns.Count ? expIndexLeft + 1 : 0;
expIndexRight = expIndexMiddle + 1 < transBtns.Count ? expIndexMiddle + 1 : 0;

transBtns[indexBtnNeedHide].localPosition = posHide;
transBtns[indexBtnNeedHide].localScale = scaleBtnMiddle / Mathf.Pow(rateScale, 2);
transBtns[expIndexLeft].localPosition = posBtnsShow[0];
transBtns[expIndexLeft].localScale = scaleBtnMiddle / rateScale;
transBtns[expIndexMiddle].localPosition = posBtnsShow[1];
transBtns[expIndexMiddle].localScale = scaleBtnMiddle;
transBtns[expIndexRight].localPosition = posBtnsShow[2];
transBtns[expIndexRight].localScale = scaleBtnMiddle / rateScale;

按钮点击事件

按钮点击事件的添加并不特别,相较麻烦的是需要在按钮移动后实现事件,移动方向就成了必要判断。可点击到的按钮一定为遮罩内可见的按钮,因此可获取当前点击的按钮位置来进行判断移动方向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值