[UnityUI]循环滑动列表
效果图:
使用的是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]循环滑动列表的更多相关文章
- [UGUI]滑动列表优化(循环利用)
需要注意的有下面几点: 1. 区分好表现上的index和逻辑上的index.表现上的index是指这个go是go列表中的第几项,但实际上这个index的意义并不大,因为在滚动的过程中go列表是轮转的: ...
- Android使用ViewPager实现左右循环滑动及轮播效果
边界的时候会看到一个不能翻页的动画,可能影响用户体验.此外,某些区域性的ViewPager(例如展示广告或者公告之类的ViewPager),可能需要自动轮播的效果,即用户在不用滑动的情况下就能够看到其 ...
- Jquery制作--循环滚动列表
自己模仿JQ插件的写法写了一个循环滚动列表插件,支持自定义上.下.左.右四个方向,支持平滑滚动或者间断滚动两种方式,都是通过参数设置.JQ里面有些重复的地方,暂时没想到更好的方法去精简.不过效果还是可 ...
- viewpage 循环滑动播放图片
一般来说,viewpage 只支持图片的顺序滑动播放,在滑到边界时就再也滑不动了,如果要想继续滑动,只能向两边额外增加一张相片,即把第一张相片的位置放在最后一张图片的后面,给用户的感觉我继续滑就滑到了 ...
- 自定义循环滑动的viewpager
今天和大家分享一下如何定制一个可以循环滑动的viewpager.其实今天更重要的提供一种组件化思想,当然你可以理解为面向对象思想. 吐槽一下网上流行的实现方式吧(为了方便说明,下文称之为方式A),方式 ...
- android中无限循环滑动的gallery实例
android中无限循环滑动的gallery实例 1.点击图片有变暗的效果,使用imageview.setAlpha(),并且添加ontouchListener public void init() ...
- Unity3d NGUI的使用(九)(UIScrollView制作滑动列表)
UIScrollView制作滑动列表,可横向,竖直展示一些列表在固定可视范围内 UIScrollVIew只是一个可滑动的UI组件 如果需要制作复杂的可视区域UI需要配合使用UIPanel与UIGrid ...
- 多行滚动jQuery循环新闻列表代码
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- 使用泛型简单封装NGUI的ScrollView实现滑动列表
懒,是老毛病了,周末跑了半马,跑完也是一通累,好久没锻炼了..也是懒的,有时都懒的写博客..最近看到项目中各种滑动列表框,本着要懒出水平来的原则,决定花点时间简单处理下(暂时未做列表太多时的优化):1 ...
随机推荐
- 34.share_ptr智能指针共享内存,引用计数
#include <iostream> #include <memory> #include <string> #include <vector> us ...
- POJ 2373 单调队列优化DP
题意: 思路: f[i] = min(f[j]) + 1; 2 * a <= i - j <= 2 *b: i表示当前在第i个点.f[i]表示当前最少的线段个数 先是N^2的朴素DP(果断 ...
- HDFS的安全模式
- 使用python fabric搭建RHEL 7.2大数据基础环境以及部分优化
1.使用python fabric进行Linux基础配置 使用python,可以让任何事情高效起来,包括运维工作,fabric正式这样一套基于python2的类库,它执行本地或远程shell命令提供了 ...
- VS导出方法名和方法备注的方法
VS导出方法名和方法备注的方法 方法一: 只能导出图片格式的UML 类图 1.点击查看类图 2.在空白处点击讲关系导出为图像 方法二: 是把整个类库的方法名都罗列出来 这个方便整理一些 具体方法如下 ...
- Windows Phone相关
Windows Phone IP over USB Transport (IpOverUsbSvc) is not running 进“服务”搜索 “Windows Phone IP Over USB ...
- [国家集训队]整数的lqp拆分 数学推导 打表找规律
题解: 考场上靠打表找规律切的题,不过严谨的数学推导才是本题精妙所在:求:$\sum\prod_{i=1}^{m}F_{a{i}}$ 设 $f(i)$ 为 $N=i$ 时的答案,$F_{i}$ 为斐波 ...
- PHP实现杨辉三角形
<?php /**** * 杨辉三角形:我的实现方式. * 下标 * 1 0 * 1 1 1 循环上一行数据1次,计算后结果追加到当前行末尾 * 1 2 1 2 * 1 3 3 1 3 * 1 ...
- 在MAC上安装lxml到Python3
首先可以直接使用以下命令安装lxml,但是会默认安装到Python2,没有找到怎么指定安装到Python3 sudo easy_install lxml 想要安装到Python3需要先安装pip: s ...
- C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件
原文:C#开发奇技淫巧二:根据dll文件加载C++或者Delphi插件 这两天忙着把框架改为支持加载C++和Delphi的插件,来不及更新blog了. 原来的写的框架只支持c#插件,这个好做 ...