效果图:

使用的是UGUI和DOTween

当中比較关键的是循环滑动和层次排序:

1.循环滑动:这里先如果显示五张图片。分别标记为0,1,2,3,4,那么当向左滑动时,序列就变为1,2,3,4,0,这里先保存4的位置,然后从4開始,4的位置和大小向3渐变,3的位置和大小向2渐变。2的位置和大小向1渐变。1的位置和大小向0渐变。0的位置直接变为原来保存的4的位置。

也就是说,当向左滑动时,最左端的那张图片特殊处理,其余的向左推进。当向右滑动时,最右端的那张图片特殊处理,其余的向右推进。

2.层次排序:因为使用的是UGUI。UI的排序跟在Hierarchy的位置有关。假设图片缩放得越小,就觉得它越远离屏幕。因此就越靠前。会被后面的图片遮住。注意的是在缩放动画播放时,localScale是不确定的,因此要直接将当前位置的下一个位置的localScale传入,从而计算图片的"深度"。还有就是使用SetSiblingIndex时要全然确定好全部图片的排序。

using UnityEngine;
using System.Collections.Generic;
using DG.Tweening; public class ScrollView : MonoBehaviour { public int xOffset = 1;//x轴偏移
public int yOffset = 0;//y轴偏移
public float scale = 0.8f;//缩放倍数
public float time = 0.5f;//偏移与缩放动画的播放时间 private int left;//最左端的编号
private int right;//最右端的编号
public int itemAmount = 5;//展示的图片数
public Vector3 middlePos;//最中间的位置 public GameObject itemPrefab;
private GameObject canvas;
private GameObject[] sortArray;
private List<GameObject> list = new List<GameObject>(); private void InstantiateItem(Vector3 pos,float scale)
{
GameObject go = Instantiate(itemPrefab) as GameObject;
go.transform.SetParent(canvas.transform);
go.transform.localPosition = pos;
go.transform.localScale *= scale; InsertToSortArray(go, go.transform.localScale.x);
list.Add(go);
} public void Init()
{
left = 0;
right = itemAmount - 1;
canvas = GameObject.Find("Canvas");
sortArray = new GameObject[itemAmount]; int oneSideAmount = (itemAmount - 1) / 2; for(int i = oneSideAmount;i >= 1;i--)
{
Vector3 pos = middlePos + new Vector3(i * xOffset,i * yOffset,0) * -1;
InstantiateItem(pos,Mathf.Pow(scale,i));
} InstantiateItem(middlePos,1); for(int i = 1;i <= oneSideAmount;i++)
{
Vector3 pos = middlePos + new Vector3(i * xOffset,i * yOffset,0);
InstantiateItem(pos,Mathf.Pow(scale,i));
} Sort();
} /// <summary>
/// 依据缩放倍数计算深度
/// </summary>
/// <param name="scaleNum"></param>
/// <returns></returns>
private int CalculateDepth(float scaleNum)
{
float num = 0;
int i = 0;
while (true)
{
num = Mathf.Pow(scale, i);
if (num != scaleNum) i++;
else break;
}
return i;
} /// <summary>
/// 插入到排序数组中。数组序号越低。则越远离屏幕
/// </summary>
/// <param name="go"></param>
/// <param name="localScaleX"></param>
private void InsertToSortArray(GameObject go, float localScaleX)
{
int depth = CalculateDepth(localScaleX);
depth = itemAmount / 2 - depth; if (depth == itemAmount / 2)
sortArray[depth * 2] = go;
else if (sortArray[depth] == null)
sortArray[depth] = go;
else
sortArray[depth + itemAmount / 2] = go;
} private void Sort()
{
for (int i = 0; i < itemAmount; i++)
{
sortArray[i].transform.SetSiblingIndex(i);
}
sortArray = new GameObject[itemAmount];
} public void Move(int direction)
{
if(direction == -1)//向左滑动
{
int startIndex = left;
int lastIndex = right;
Vector3 lastPos = list[lastIndex].transform.position; InsertToSortArray(list[startIndex], list[startIndex].transform.localScale.x); for (int i = 0; i < itemAmount - 1;i++ )
{
int index = (lastIndex - i + itemAmount) % itemAmount;
int preIndex = (index - 1 + itemAmount) % itemAmount;
list[index].transform.DOMove(list[preIndex].transform.position,time);
list[index].transform.DOScale(list[preIndex].transform.localScale,time); InsertToSortArray(list[index], list[preIndex].transform.localScale.x);
} list[startIndex].transform.DOMove(lastPos,time); left = (left + 1) % itemAmount;
right = (right + 1) % itemAmount;
}
else if (direction == 1)//向右滑动
{
int startIndex = right;
int lastIndex = left;
Vector3 lastPos = list[lastIndex].transform.position; InsertToSortArray(list[startIndex], list[startIndex].transform.localScale.x); for (int i = 0; i < itemAmount - 1; i++)
{
int index = (lastIndex + i + itemAmount) % itemAmount;
int preIndex = (index + 1 + itemAmount) % itemAmount;
list[index].transform.DOMove(list[preIndex].transform.position, time);
list[index].transform.DOScale(list[preIndex].transform.localScale, time); InsertToSortArray(list[index], list[preIndex].transform.localScale.x);
} list[startIndex].transform.DOMove(lastPos, time); left = (left - 1 + itemAmount) % itemAmount;
right = (right - 1 + itemAmount) % itemAmount;
} Sort();
}
}

不足之处:

1.仅仅适用于展示图片数为奇数的场合

2.等等...

[UnityUI]循环滑动列表的更多相关文章

  1. [UGUI]滑动列表优化(循环利用)

    需要注意的有下面几点: 1. 区分好表现上的index和逻辑上的index.表现上的index是指这个go是go列表中的第几项,但实际上这个index的意义并不大,因为在滚动的过程中go列表是轮转的: ...

  2. Android使用ViewPager实现左右循环滑动及轮播效果

    边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...

  3. Jquery制作--循环滚动列表

    自己模仿JQ插件的写法写了一个循环滚动列表插件,支持自定义上.下.左.右四个方向,支持平滑滚动或者间断滚动两种方式,都是通过参数设置.JQ里面有些重复的地方,暂时没想到更好的方法去精简.不过效果还是可 ...

  4. viewpage 循环滑动播放图片

    一般来说,viewpage 只支持图片的顺序滑动播放,在滑到边界时就再也滑不动了,如果要想继续滑动,只能向两边额外增加一张相片,即把第一张相片的位置放在最后一张图片的后面,给用户的感觉我继续滑就滑到了 ...

  5. 自定义循环滑动的viewpager

    今天和大家分享一下如何定制一个可以循环滑动的viewpager.其实今天更重要的提供一种组件化思想,当然你可以理解为面向对象思想. 吐槽一下网上流行的实现方式吧(为了方便说明,下文称之为方式A),方式 ...

  6. android中无限循环滑动的gallery实例

    android中无限循环滑动的gallery实例 1.点击图片有变暗的效果,使用imageview.setAlpha(),并且添加ontouchListener public void init() ...

  7. Unity3d NGUI的使用(九)(UIScrollView制作滑动列表)

    UIScrollView制作滑动列表,可横向,竖直展示一些列表在固定可视范围内 UIScrollVIew只是一个可滑动的UI组件 如果需要制作复杂的可视区域UI需要配合使用UIPanel与UIGrid ...

  8. 多行滚动jQuery循环新闻列表代码

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  9. 使用泛型简单封装NGUI的ScrollView实现滑动列表

    懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了..也是懒的,有时都懒的写博客..最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):1 ...

随机推荐

  1. CUDA学习笔记(四)

    昨天一直在写ben的作业.总结一下周一的cuda情况. cuda程序需要用到一些设置的参数,如argv[],另外cuda读入文件特别苛刻,只能采用C的方式,而且对w+,r的使用只有试通才行. 卧底天外 ...

  2. Ionic CLI升级到3版本后2版本工程运行出错.md

    1. 问题描述: 最近将Ionic的CLI升级到了最新的版本3.2,升级后在原来Ionic2版本的CLI中创建的工程,通过ionic serve运行报错,错误类似如下: C:\Users\Admin\ ...

  3. 51Nod 1433 0和5(数论)

    小K手中有n张牌,每张牌上有一个一位数的数,这个字数不是0就是5.小K从这些牌在抽出任意张(不能抽0张),排成一行这样就组成了一个数.使得这个数尽可能大,而且可以被90整除. 注意: 1.这个数没有前 ...

  4. df 显示 100%的问题

    问题:         使用 df 命令查看,某个分区使用率已经达到100%,但是用du 命令统计该分区,发现该分区空间剩余10G可用.         实例:                分析: ...

  5. GenIcam标准介绍

    GenICam TM的目标是为各种相机和设备提供通用编程接口.无论他们使用什么接口技术(GigE Vision,USB3 Vision,CoaXPress,Camera Link HS,Camera ...

  6. 从头认识java-18.2 主要的线程机制(5)-守护线程与非守护线程

    这一章节我们来讨论一下守护线程与非守护线程. 1.什么是守护线程?什么是非守护线程? 非守护线程:Java虚拟机在它全部非守护线程已经离开后自己主动离开. 守护线程:守护线程则是用来服务用户线程的,假 ...

  7. CODE ---代码助手 (保存代码、搜代码、生成网页、自由界面)

    四大功能 1  保存代码 2  搜索代码 3  生成网页 4  自由界面 www.gudianxiaoshuo.com

  8. 3.AngularJS-过滤器

    转自:https://www.cnblogs.com/best/p/6225621.html 二.过滤器 使用过滤器格式化数据,变换数据格式,在模板中使用一个插值变量.语法格式如下: {{ expre ...

  9. 101.C++继承三种权限

    三种访问权限 public:可以被任意实体访问 protected:只允许子类及本类的成员函数访问 private:只允许本类的成员函数访问 三种继承特点 1.public继承不改变基类成员的访问权限 ...

  10. easyUI表单验证

    1.重写easyui中的 $.extend($.fn.validatebox.defaults.rules, { }) 2.长度重写的方式 1 $.extend($.fn.validatebox.de ...