如下图所示,这是我们的工程页面,程序的实现原理是将相册在Unity3D世界中呈横向队列,摄像机固定的照射在第一个Item相册,当手指发生滑动事件时,计算向左滑动还是向右滑动,此时整体移动相册队列,而摄像机不动。为了让滑动效果更加好看我们需要使用插值计算滑动的时间,使滑动队列不是直接移动过去,而是以一定惯性移动过去。相册下方我们制作一个小白点用来记录当前滑动的位置,在做几个灰色的点表示队列一共的长度,滑动时下方的小白点也会跟随移动,这样就更想高级控件啦。当然小白点与小灰点是要根据item的数量居中显示的喔。

注解1:滚动相册一般可分为两种,第一种为数量已知的情况,第二种为数量未知的情况。因为第一种比较简单所以我们主要探讨第二种。

Script historyInit.cs: 该脚本用于相册队列的初始化工作。在这里初始化相册队列的数量,计算完毕让队列以横向线性的排列方式在Unity3D中。

Prefab item:每个相册的预设,我这里每个相册上还会有一些文字的描述,我需要动态的修改它们的内容。大家也可根据自己的情况制作自己的相册item。

Prefabhui:相册滚动时下方用来记录相册队列总数的灰色小点。

Prefabbai :相册滚动时下方用来记录当前滚动页面ID的白色小点。

Point :因为灰色、白色的点不能和相册队列在一个面板之上,否则会跟着相册队列移动而移动,所以这里将灰色白色的点放在两外一个面板之上。

注解2:这个面板上的4个item就是我们通过historyinit脚本初始化时动态生成赋值的、当界面发生触摸事件时,会整体移动该面板让自对象的相册队列跟随移动。

注解3:button0 – button3 是下方的Tabar。bai(Clone)表示白色的小点,hui(Clone)表示灰色的小点,它们的位置是需要根据滑动事件而改变的。

因为我们需要监听每一个Item的滑动事件,所以肯定要在每一个item预设之上绑定监听事件的脚本,如下图所示。

注解1:因为需要监听触摸滑动事件,所以肯定要绑定Box Collider组件,这个是NGUI的标准用法。

注解2:Move脚本用来监听向左滑动 向右滑动 点击事件。

注解3:这个就是每一个相册的item,在上图中挂在historyInit脚本之上。

historyInit.cs

001 using UnityEngine;
002 using System.Collections;
003 using System.Collections.Generic;
004  
005 public class historyInit  :MonoBehaviour
006 {
007  
008     //相册列表的每一个item
009     public GameObject prefab;
010     //灰色的小点
011     public GameObject prefabhui;
012     //白色的小点
013     public GameObject prefabbai;
014     //另外一个显示面板
015     //用来放置灰色、白色小点
016     public Transform  ponit;
017     //白色小点的临时对象
018     private GameObject bai;
019  
020     //链表,用来记录每一个相册中的一些用户信息
021     List<UserData> users = new List<UserData>();
022     //灰色、白色小点下方的起始位置。
023     int start;
024  
025     void Start ()
026     {
027         //将当前面板对象储存在全局静态变量中
028         Globe.ListPanel = gameObject;
029         loadSQL ();
030         initItem();
031     }
032  
033     //以前是读取数据库
034     //写例子程序就没必要使用数据库了
035     //这里直接写4个死值,当然数量是灵活使用的
036  
037     void loadSQL ()
038     {
039         //表示一共向U3D世界中添加横向4个相册队列
040         for(int i =0; i< 4; i ++)
041         {
042             //简单的对象储存
043             string  name =  "momo =" + i;
044             string  age =  "26 = " + i;
045             string  height = "183 ="+ i;
046             users.Add(new UserData(name,age,height));
047         }
048  
049     }
050  
051     void initItem()
052     {
053         //因为下方灰色 白色的小点需要根据相册列表的数量来计算居中显示
054         int size = users.Count;
055         //乘以16表示计算所有小点加起来的宽度
056         int length = (size - 1) * 16;
057         //得到下方灰色 白色 小点的居中起始位置
058         start = (-length) >>1;
059  
060         for(int i=0; i< size; i++)
061         {
062             //把每一个相册加入相册列表
063             GameObject o  =(GameObject) Instantiate(prefab);
064             //设置这个对象的父类为 当前面板
065             o.transform.parent = transform;
066             //设置相对父类的坐标,这些值可根据自己的情况而设定,
067             //总之就是设置相册列表中每一个item的坐标,让它们横向的排列下来就行
068             o.transform.localPosition = new Vector3(25 + i* 243,-145f,-86f);
069             //设置相对父类的缩放
070             o.transform.localScale= new Vector3(0.7349999f,0.66f,0.7349999f);
071  
072             //得到每一个user的信息
073             UserData data = users[i];
074             //遍历每一个相册对象的子组件,
075             UILabel []label = o.GetComponentsInChildren<UILabel>();
076             //拿到UILabel并且设置它们的数据
077             label[0].text = data.age;
078             label[1].text = data.height;
079             label[2].text = data.name;
080  
081             //把每一个灰色小点加入3D世界
082             GameObject hui  =(GameObject) Instantiate(prefabhui);
083             //设置灰色小点的父类为另外一个面板
084             hui.transform.parent = ponit;
085             //设置每一个灰色小点的位置与缩放,总之让它们居中排列显示在相册列表下方。
086             hui.transform.localPosition = new Vector3(start + i* 16,-120f,0f);
087             hui.transform.localScale= new Vector3(8,8,1);
088  
089             //深度 因为是先在屏幕下方绘制4个灰色的小点, 然后在灰色上面绘制白色小点
090             //表示当前的窗口ID 所以深度是为了设置白色小点在灰色小点之上绘制
091             hui.GetComponent<UISprite>().depth = 0;
092         }
093  
094         //下面的数据是把当前初始化的数据放在一个static类中
095         //在Move脚本中就可以根据这里的数据来判断了。
096         //滑动列表的长度
097         Globe.list_count = size -1;
098         //相册每一项的宽度
099         Globe.list_offset = 243;
100         //当前滑动的索引
101         Globe.list_currentIndex = 0;
102         //点击后打开的新游戏场景
103         Globe.list_go_name= "LoadScene";
104  
105         //把白色小点也加载在3D世界中
106         bai  =(GameObject) Instantiate(prefabbai);
107         //设置它的深度高于 灰色小点,让白色小点显示在灰色小点之上
108         bai.GetComponent<UISprite>().depth = 1;
109         //设置白色小点的位置
110         setBaiPos();
111     }
112  
113     void Update()
114     {
115         //当用户滑动界面
116         //在Update方法中更新
117         //当前白色小点的位置
118         setBaiPos();
119     }
120  
121     void setBaiPos()
122     {
123         //Globe.list_currentIndex 就是当前界面的ID
124         //根据ID 重新计算白色小点的位置
125         bai.transform.parent = ponit;
126         bai.transform.localPosition = new Vector3(start + Globe.list_currentIndex* 16,-120f,-10f);
127         bai.transform.localScale= new Vector3(8,8,1);
128  
129     }
130 }

如下图所示,我们可以看出Tabbar 、 下方记录界面的灰色、白色小点、摄像机  它们是不会发生改变的。唯一改变的就是面板之上的相册队列。为了让滑动界面的效果更加连贯,我们需要以插值的形式来计算真个相册面板的坐标。

触摸的事件全都写在Move.cs脚本中。

01 using UnityEngine;
02 using System.Collections;
03  
04 public class Move : MonoBehaviour {
05  
06     //是否触摸
07     bool isTouch = false;
08     //是否向左滑动
09     bool isRight = false;
10     //是否向右滑动
11     bool isLeft = false;
12     //是否正在滑动中
13     bool isOnDrag = false;
14  
15     //滑动中事件
16     void OnDrag (Vector2 delta)
17     {
18         //为了避免事件冲突
19         //这里只判断一个滑动的事件
20         if(!isTouch)
21         {
22             if(delta.x > 0.5)
23             {
24                 //向左滑动
25                 isRight = true;
26                 isOnDrag = true;
27             }else if(delta.x < -0.5)
28             {
29                 //向右滑动
30                 isLeft = true;
31                 isOnDrag = true;
32             }
33             isTouch = true;
34         }
35     }
36  
37     //滑动后松手调用OnPress事件
38     void OnPress()
39     {
40         //重新计算当前界面的ID
41         if(Globe.list_currentIndex < Globe.list_count && isLeft)
42         {
43             Globe.list_currentIndex++;
44         }
45  
46         if(Globe.list_currentIndex >0 && isRight)
47         {
48             Globe.list_currentIndex--;
49         }
50  
51         //表示一次滑动事件结束
52         isTouch = false;
53         isLeft = false;
54         isRight = false;
55     }
56  
57     void Update()
58     {
59         //这个方法就是本节内容的核心
60         //Globe.ListPanel 这个对象是我们在historyInit脚本中得到的,它用来当面相册面板对象使用插值,让面板有惯性的滑动。
61  
62         //Vector3.Lerp() 这个是一个插值的方法, 参数1 表示开始的位置 参数2 表示结束的位置  参数3 表示一共所用的时间, 在Time.deltaTime * 5 时间以内 Update每一帧中得到插值当前的数值,只到插值结束
63  
64         //-(Globe.list_currentIndex * Globe.list_offset) 得到当前需要滑动的目标点。
65         //请大家仔细看这个方法。
66  
67         Globe.ListPanel.transform.localPosition =Vector3.Lerp(Globe.ListPanel.transform.localPosition, new Vector3(-(Globe.list_currentIndex * Globe.list_offset),0,0), Time.deltaTime * 5);
68     }
69  
70     void OnClick ()
71     {
72         //当点击某个item时进入这里
73  
74         if(!isOnDrag)
75         {
76             //如果不是在拖动中 进入另一个场景
77             Application.LoadLevel(Globe.list_go_name);
78         }
79         else
80         {
81             //否则等待用户重新发生触摸事件
82             isOnDrag = false;
83         }
84     }
85 }

还有两个辅助的类,我也贴出来。

UserData.cs

01 using UnityEngine;
02 using System.Collections;
03  
04 public class UserData{
05  
06     public string name;
07     public string age;
08     public string height;
09     public string hand;
10  
11     public UserData(string _name, string _age,string _height)
12     {
13         age = _age;
14         height = _height;
15         name = _name;
16     }
17  
18 }

Globe.cs 这个静态类用来共享记录多个脚本甚至多个场景所需的数据。

01 using System.Collections.Generic;
02 public class Globe
03 {
04  
05      public static GameObject ListPanel;
06      public static int list_count;
07      public static int list_currentIndex;
08      public static int list_offset;
09      public static string list_go_name;
10  
11 }

写到这里,本篇博文就写的差不多了。这篇文章我是用NGUI来实现的触摸滚动效果,仔细想想,其实不用NGUI完全也能实现这样的效果。在脚本中完全可以通过射线 以及 触摸的时间去计算当前用户操作的事件,这篇文章里的工程最后我是打包在Android上面的,效果挺不错,滑动的效果图不好截取我也不截取了,主要还是文章的书写内容,希望大家学习愉快,雨松MOMO祝大家晚安,哇咔咔,啦啦啦。

NGU- Scroll View实现触摸滚动相册效果相关推荐

  1. 重新计算ListView的高度,解决ScrollView和ListView两个View都有滚动的效果,在嵌套使用时解决冲突的问题

    public static void setListViewHeight(ListView listView) {// 获取ListView对应的AdapterListAdapter listAdap ...

  2. (Endless)Scroll View(画卷滚动视图)

    就像酱紫,可以左右拖拉或者用下面的拉动条滚动. 之前做过Endless scroll view(无止境的画卷视图)的,像环状一样,左边拉完,会从右边出来,右边从左边出来 先把Endless scrol ...

  3. 如何在Storyboard中使用Scroll view

    本文章环境Xcode 11 在开始使用scroll view之前(storyboard/XIB),我们必须搞清楚两个东西 在Storybord/Xib中使用Scroll view,会有哪些结构 为什么 ...

  4. 【NGUI基础知识】—Scroll View(滚动视图)详解

    下面给大家分享下NGUI中Scroll View(滚动视图)中的各功能属性,帮助大家去理解及使用. ScrollView属性 1.Content Origin: 控制 panle 相对的 Scroll ...

  5. Unity UGUI基础 之 Scroll View/Scroll Rect 的简单使用,并取消拖拽(滑动内容)效果,拖拽只在Scrollbar 上起作用

    Unity UGUI基础 之 Scroll View/Scroll Rect 的简单使用,并取消拖拽(滑动内容)效果,拖拽只在Scrollbar 上起作用 目录 Unity UGUI基础 之 Scro ...

  6. Unity3D UGUI Scroll View 二级滚动菜单

    前言 如果有更好的写法或是代码有什么错误等等,还请大佬教教我. 最终效果 大概就这么个效果,使用的Scroll View做的,我使用的是中文版,看不懂英文,没得法 准备 预制件(各预制件结构在文中会有 ...

  7. 【UGUI】Scroll View滚动视图

    Scroll View 组成 回顾Scrollbar滚动条 Scroll Rect组件 Content:可以滚动的内容,该对象必须是带有Scroll Rect的子控件 Horizontal:数据是否可 ...

  8. android 半圆滚动菜单,自定义控件:实现半圆滚动菜单效果

    前言 本自定义控件参考自鸿洋大神的自定义控件,基于原来的控件效果进行修改,着重实现了以下效果:位置自动修正以及滑动结束的回调.我们先来看看效果图: 上面的图片是一个ImageView,与控件无关,是为 ...

  9. 分享92个JS相册效果JS代码,总有一款适合你

    分享92个JS相册效果JS代码 链接:https://pan.baidu.com/s/10AUc6EN5TB4ZPydLAAEu5Q  提取码:pxj1 下面是文件的名字,我放了一些图片,文章里不是所 ...

最新文章

  1. 使用python爬虫抓站的一些技巧总结:进阶篇
  2. 10-Python与设计模式--享元模式
  3. Jquery学习笔记:删除节点的操作
  4. 定量遥感:计算地方时和太阳高度角(C++代码)
  5. 正则表达式必知必会学习笔记
  6. 闲话WPF之十三(WPF中的资源)
  7. Java数据类型及类型转换
  8. H3CSE园区-STP
  9. java/php/net/python大学生就业管理系统设计
  10. IOS-App Store 提审应用步骤
  11. 桌面排版神器:Affinity Publisher for Mac
  12. oracle打开audit,oracle开启audit(审计)
  13. Mac 查看本机端口占用
  14. 服务器 ftp查询文件是否存在,ftp查看远程服务器文件是否存在
  15. dwa_planner解读
  16. 神经网络与傅立叶变换到底有没有关系?
  17. Java数据库的备份与恢复
  18. 计算机毕业设计asp.net校园美食派送系统(源码+系统+mysql数据库+Lw文档)
  19. Pop!_OS安装与配置(一):下载安装
  20. 神经网络反向传播的矩阵复合求导计算

热门文章

  1. 设计模式 之 桥接模式 //依旧是游戏中的例子来解释设计模式
  2. 实战商城app之uView框架前端极速开发课程简介
  3. 华为手机上方有“HD”标识?其实是开启了这个实用功能
  4. 你肯定不知道Java 对象不再使用时,为什么要赋值为 null ?
  5. Unity之人脸识别对比(一) 基于ArcFace离线Sdk的开发
  6. 重视肠道微生态平衡 提升抗新冠病毒免疫力
  7. 苹果x防水测试软件,iPhoneX防水吗
  8. highlight.js怎么识别br换行符
  9. PHP-ThinkPHP5砍价活动相关设计
  10. j-flash可以正常连接并进行烧录,但是keil里面识别不了