预览效果,切换过程顺滑
使用最后一次滑动的方向来判定目标方向,如果朝某边偏移后往回移动,会返回到原来的位置
支持代码设置索引直接跳转
不需要手动设置宽度,自动根据当前子类来设置滑动距离,支持动态添加和删除
使用方法:
0 新建脚本,重命名为Slider,复制代码保存
1 新建Scroll View控件,修改长宽为600*200
2 将Content锚点改为如图所示,并添加图中2个组件并设置变量
3 添加页面数据,以Image为例(按钮或Panel皆可,但尺寸需要保持一致),设置尺寸为600*200,然后Ctrl+D复制多份,Content会自动拉伸长度
4 选择Scroll View,按照图中关闭Vertical与Inertil(滑动惯性),删除用不上的Scrollbar Vertical纵向滑条,加入Slide脚本,把Content拖入变量
然后点击运行,就可以看见上面的效果了
5 附加代码
//跳转到指定节点,如果不存在会返回false
bool isSucceed = GetComponent().ToAppointNode(int 指定节点)1
//返回当前所在的节点
int x = GetComponent().GetCurNodeCount()1
//返回当前总节点数(也就是Content的子对象数)
int x = GetComponent().GetMaxNodeCount()1
//注册回调,切换不同页面时触发
GetComponent().SubscribeCallback(Action callback);1
//解除回调
GetComponent().UnSubscribeCallback();1
代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
public class Slide : MonoBehaviour, IEndDragHandler, IDragHandler, IBeginDragHandler
{ //按下时判断目标方向,松开时根据当前偏移方向与目标方向,计算目标节点,然后移动至该节点 //脚本需要放置在Scroll View组件中,MovementType设为Unrestricted,关闭Inertia //引用框 [Header("Content组件")] public GameObject content; //节点数量 int nodeCount = 0; //节点宽度/切换长度 float nodeWidth = 0; //切换速度 [Header("切换速度")] public float speed = 12; //当前所在节点 int curNode = 0; //目标节点 int targetNode = 0; //当前触摸坐标 float curTouchPos = 0; //上一帧触摸坐标 float lastTouchPos = 0; //当前触摸状态 bool isTouch = false; //切换目标方向 bool switchTargetIsLeft = false; //当前偏移方向 bool offsetIsLeft = false; //是否到达目标 bool isArrive = true; //切换瞬间的回调 public Action switchCallback = null; //按下 public void OnBeginDrag(PointerEventData eventData) { isTouch = true; lastTouchPos = eventData.position.x; curTouchPos = eventData.position.x; } //拖拽 public void OnDrag(PointerEventData eventData) { curTouchPos = eventData.position.x; //设置滑动方向 if (lastTouchPos - curTouchPos < 0) switchTargetIsLeft = true; else if (lastTouchPos - curTouchPos > 0) switchTargetIsLeft = false; lastTouchPos = eventData.position.x; } //松开 public void OnEndDrag(PointerEventData eventData) { isTouch = false; //设为未到达 isArrive = false; //更新节点信息 UpdateNodeData(); //判断当前节点偏移方向 if (content.GetComponent().anchoredPosition.x * -1 < curNode * nodeWidth)//如果当前UI坐标 < 当前节点坐标 offsetIsLeft = true; else offsetIsLeft = false; //如果目标方向和偏移方向一致 if ((switchTargetIsLeft == offsetIsLeft) && ((switchTargetIsLeft && (curNode - 1 >= 0)) || //且 朝左时没有超过最小值 (!switchTargetIsLeft && curNode + 1 <= nodeCount - 1)))//且 朝右时没有超过最大值 { //设置目标节点 targetNode = switchTargetIsLeft ? curNode - 1 : curNode + 1; //更新当前节点 curNode = targetNode; //触发回调 switchCallback?.Invoke(targetNode); } //否则回到原始位置 else { //回到当前节点 targetNode = curNode; } } //获取当前节点数 public int GetCurNodeCount() { //更新节点信息 UpdateNodeData(); return curNode; } //获取总节点数 public int GetMaxNodeCount() { //更新节点信息 UpdateNodeData(); return nodeCount; } //前往指定节点 public bool ToAppointNode(int appointNode) { //更新节点信息 UpdateNodeData(); if (appointNode < 0 || appointNode >= nodeCount) { //Debug.LogError("指定节点超出范围:"); return false; } isArrive = false; //触发回调 if (appointNode != curNode) switchCallback?.Invoke(appointNode); //设置目标节点 targetNode = appointNode; //更新当前节点 curNode = targetNode; return true; } //注册回调 public void SubscribeCallback(Action newCallback) { switchCallback = newCallback; } //清空回调 public void UnsubscribeCallback() { switchCallback = null; } //更新节点总数和每个节点的宽度 void UpdateNodeData() { //获取节点总数(所有子类) nodeCount = content.transform.childCount; //获取每个节点的宽度 nodeWidth = content.GetComponent().rect.width / nodeCount; } void Update() { //如果 不在点击状态 且 没有到达目标节点 if (!isTouch && !isArrive) { //前往目标节点 Vector2 targetPos = new Vector2( targetNode * nodeWidth * -1, content.GetComponent().anchoredPosition.y); content.GetComponent().anchoredPosition = Vector2.Lerp(content.GetComponent().anchoredPosition, targetPos, Time.deltaTime * speed); //如果很靠近 if (Mathf.Abs(content.GetComponent().anchoredPosition.x - targetPos.x) <= 0.05) isArrive = true; } }
}1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
萌新需要多多支持,如果对你有帮助,就请点个赞吧~
文章来源: blog.csdn.net,作者:Mirage狼,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/MirageWolf/article/details/110629986