左右轮播与上下轮播效果实现
话不多说,咱直接直接进入正题首先创建一个Roll_BankItem的脚本,将其挂在需要实现轮播的物体上,再创建一个Roll_BankManager脚本并创建一个空物体将其挂在上面,将轮播物体全放在空物体下。话不多说直接上代码:
#Roll_BackItem脚本
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 获取轮播对象的属性
/// </summary>
public class Roll_BankItem :MonoBehaviour
{
public float LocalPositionY//锤直方向 若想实现X轴(水平方向)的轮播将下方的value换至对应的位置
{
get { return transform.localPosition.y; }
set { transform.localPosition = new Vector3(transform.localPosition.x, value, transform.position.z); }
}
public float LocalScale//缩放
{
get { return transform.localScale.x; }
set { transform.localScale=Vector3.one * value; }
}
public int SiblingIndexs//层级
{
get { return transform.GetSiblingIndex(); }
set { transform.SetSiblingIndex(value); }
}
}
#Roll_BankManager
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using DG.Tweening;
public class Roll_BankManager : MonoBehaviour
{
/// <summary>
/// 状态枚举
/// </summary>
private enum RotationState
{
Rotating,
Stop
}
public int indexCenter = 0;//初始中间位置的Id
public float scaleMutiple=1.0f;//缩放倍数
public float cellWith = 475.0f;//宽度
public float speed = 5.0f; //速度
private List<Roll_BankItem> rotationItems = new List<Roll_BankItem>();//轮播对象集合
private List<int> relativePostions=new List<int>();//相对位置
private int indexHalf=0;//轮播数据的中值
private List<int> order=new List<int>();//顺序
private RotationState state = RotationState.Stop;
private void Awake()
{
rotationItems.AddRange(transform.GetComponentsInChildren<Roll_BankItem>());//将轮播对象加入列表
}
private void Start()
{
Init();
}
private void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow))//上
{
DoRotateItems(1);
}
if (Input.GetKeyDown(KeyCode.DownArrow))//下
{
DoRotateItems(-1);
}
}
/// <summary>
/// 初始化
/// </summary>
private void Init()
{
indexHalf = (rotationItems.Count - 1) / 2;
for (int i = 0; i < rotationItems.Count; i++)
{
int target = i - indexHalf + indexCenter;
target = target < 0 ? target + rotationItems.Count : target >= rotationItems.Count ? target - rotationItems.Count : target;
rotationItems[i] = transform.GetChild(target).GetComponent<Roll_BankItem>();
relativePostions.Add(i - indexHalf);
}
DoRotateItems();
}
/// <summary>
/// 轮播
/// </summary>
/// <param name="value"></param>
public void DoRotateItems(int value = 0)
{
if (state == RotationState.Rotating) return;
order.Clear();
for (int i = 0; i < rotationItems.Count; i++)
{
int target = i + value;
if (target < 0)
{
target += rotationItems.Count;
}
else if (target >= rotationItems.Count)
{
target -= rotationItems.Count;
}
order.Add(target);
if ((target == 0 && value > 0) || (target == rotationItems.Count - 1 && value < 0))
{
int indexI = i;
int indexTarget = target;
rotationItems[i].transform.DOScale(0.01f, Mathf.Abs(value) / speed * 0.5f).OnComplete(() =>
{
rotationItems[indexI].LocalPositionY = relativePostions[indexTarget] * cellWith * Mathf.Pow(scaleMutiple, Mathf.Abs(relativePostions[indexTarget]));
rotationItems[indexI].transform.DOScale(Mathf.Pow(scaleMutiple, Mathf.Abs(relativePostions[indexTarget])), Mathf.Abs(value) / speed * 0.5f).SetEase(Ease.Linear);
});
}
else
{
rotationItems[i].transform.DOLocalMoveY(relativePostions[target] * cellWith* Mathf.Pow(scaleMutiple, Mathf.Abs(relativePostions[target])), Mathf.Abs(value) / speed).SetEase(Ease.Linear);
rotationItems[i].transform.DOScale(Mathf.Pow(scaleMutiple, Mathf.Abs(relativePostions[target])), Mathf.Abs(value) / speed).OnComplete(() =>
{
state = RotationState.Stop;
}).SetEase(Ease.Linear);
}
}
StartCoroutine(CallBack(Mathf.Abs(value)));
state = RotationState.Rotating;
}
/// <summary>
/// 回调(单次轮播进行到一半时,重置List、改变SiblingIndex)
/// </summary>
/// <param name="time"></param>
/// <returns></returns>
private System.Collections.IEnumerator CallBack(int time)
{
yield return new WaitForSeconds(time * 0.5f / speed);
Roll_BankItem[] newItems = new Roll_BankItem[rotationItems.Count];
for (int i = 0; i < rotationItems.Count; i++)
{
newItems[order[i]] = rotationItems[i];
}
rotationItems.Clear();
rotationItems.AddRange(newItems);
ChangeSiblingIndex();
}
/// <summary>
/// 改变层级
/// </summary>
private void ChangeSiblingIndex()
{
for (int i = 0; i < rotationItems.Count; i++)
{
int index;
index = relativePostions[i] >= 0 ? rotationItems.Count - 1 - relativePostions[i] * 2 : rotationItems.Count - 1 + relativePostions[i] * 2 + 1;
rotationItems[i].SiblingIndexs = index;
}
}
轮播