[Unity3d]NGUI- Scroll View实现触摸滚动相册效果
来源:互联网 发布:商业桌面软件 编辑:程序博客网 时间:2024/05/22 17:48
如下图所示,这是我们的工程页面,程序的实现原理是将相册在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祝大家晚安,哇咔咔,啦啦啦。
- [Unity3d]NGUI- Scroll View实现触摸滚动相册效果
- NGUI研究院之自制 Scroll View实现触摸滚动相册效果(四)
- NGUI研究院之自制 Scroll View实现触摸滚动相册效果(四)
- NGUI研究院之自制 Scroll View实现触摸滚动相册效果(四)
- NGU- Scroll View实现触摸滚动相册效果
- Unity3D NGUI Scroll View注意事项
- 【Unity3D】【NGUI】循环Scroll View
- Unity3D NGUI Scroll View注意事项
- NGUI Scroll View 循环滚动
- 实现滚动相册效果
- 【NGUI基础知识】——Scroll View(滚动视图)
- NGUI -- Scroll View
- 【NGUI】循环Scroll View
- NGUI之Scroll View
- [NGUI]用SrollViewPanel实现相册的滚动。
- unity3D -- (UGUI)Scroll View
- NGUI 例子8 scroll view
- Unity NGUI制作scroll view
- 音乐播放器
- linux中Find、whereis、locate、which查找文件命令详解
- mysql +php +mac
- Java 访问权限
- sybase iq 15.3 libXtst.so.6: cannot open shared object file: No such file or directory
- [Unity3d]NGUI- Scroll View实现触摸滚动相册效果
- myeclipse6.5安装jrable
- Oracle约束操作(表级约束)
- Hadoop 故障:java.lang.OutOfMemoryError: Java heap space
- Visual AssistX vc6&vs2003 配置
- Android4.0.3 显示系统深入理解
- 比特币怎样存放才能有效“防黑”?
- Apache MiNa 实现多人聊天室
- cocos2d-x:动画 Animations