unity滑动窗口_Unity 制作滑动窗口(滑动吸附窗口) 复制粘贴就能用

本文介绍了如何在Unity中制作一个滑动窗口,实现平滑的页面切换效果。通过调整Scroll View组件参数,配合自定义脚本实现动态添加、删除和跳转页面的功能。详细步骤包括新建脚本、配置Scroll View、添加页面数据以及提供相应的API调用来控制页面操作。
摘要由CSDN通过智能技术生成

预览效果,切换过程顺滑

使用最后一次滑动的方向来判定目标方向,如果朝某边偏移后往回移动,会返回到原来的位置

支持代码设置索引直接跳转

不需要手动设置宽度,自动根据当前子类来设置滑动距离,支持动态添加和删除

使用方法:

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值