[Unity实践笔记] 整页翻、防误触的ScrollView

Unity自带UI组件可以创建一个滑动区域 , 制作一些横屏和竖屏的滑动效果非常方便 。
效果展示:
组件简介
滚动窗口 , 可以勾选横向滑动或者竖向滑动、是否需要窗口蒙版等 。
窗口蒙版 , 限定可以看到的窗口区域 , 带有一个Image作为Mask 。在调整时想看到未遮挡的效果 , 取消勾选Image或者Mask即可 。
需要滑动显示的页面 , 可以作为多个展示物体的父物体 , 并挂载 Group自动调整布局 。

[Unity实践笔记] 整页翻、防误触的ScrollView

文章插图
滚动条 , 在里取消勾选的方向的可以删除 , 未取消勾选可以分别移除Image组件来达到隐藏滚动条的效果(记得还有) 。可以通过修改.value实现跳转 。
实践分析
如果直接使用的话 , 实际滑动中经常会出现下面的情况:
屏幕中出现上下两张不完整的图片的情况 , 并且一些细微的滑动也会造成窗口的滚动 , 不美观想要完整的看一张图片 / 想把图片放到屏幕中间需要自己手动一点一点的滑动调整 , 不方便
需求总结 不要出现屏幕中有两张图片的割裂情况不要出现手指误触导致的画面滑动

说什么废话!
直接说“翻页吸附效果”、“整页翻”不就好了???
问题分析
[Unity实践笔记] 整页翻、防误触的ScrollView

文章插图
每次滑动完毕 , 都要根据滑动幅度(距离)来判断此次滑动会不会触发翻页的效果 。
如果会 , 就翻页;反之 , 回到原来的位置 。
解决方案 为每个页面分区间 , 计算每个页面的.value获得每次滑动的距离根据距离判断是否翻页(优化:设定滑动长度占屏幕长度的百分比 , 解决多种分辨率设备的适配)
3.1. 若距离大于翻页所需值 , 翻页
3.2 反之 , 返回原页面若需翻页 , 根据滑动值正负判断翻页方向 , 注意第一页和最后一页的情况
代码如下:
public class SwitchPage : MonoBehaviour{private const float SMOOTH_TIME = 10f;public Scrollbar scrollBar;public int pageNum = 5; // 总共的图片数public float minScrollDisPercent = 0.2f;float minScrollDis; // 最小翻页需要挪动的距离float point;// 每个区间的中点value加值bool turnPage = false;float targetValue = http://www.kingceram.com/post/0f;float speed = 0f;int currentPage;int targetPage;float startX;float endX;private void Awake(){point = 1.0f / (pageNum - 1);// 根据设备分辨率的不同来计算在不同的设备上翻页所需要滑动的距离minScrollDis = Screen.currentResolution.width * minScrollDisPercent;currentPage = 0;}// Update is called once per framevoid Update(){if (turnPage){if (Mathf.Abs(scrollBar.value - targetValue) < 0.01f){scrollBar.value = targetValue;turnPage = false;return;}scrollBar.value = Mathf.SmoothDamp(scrollBar.value, targetValue, ref speed, Time.deltaTime * SMOOTH_TIME);}}public void DragStart(){turnPage = false;startX = Input.mousePosition.x;}public void DragEnd(){endX = Input.mousePosition.x;float deltaX = startX - endX;// 如果滑动距大于设定值 , 左右翻页if (Mathf.Abs(deltaX)> minScrollDis){if (deltaX > 0){targetPage = Mathf.Min(pageNum - 1, currentPage + 1);}else{targetPage = Mathf.Max(0, currentPage - 1);}// 更新currentPagecurrentPage = targetPage;}// 否则 , 返回原页else{targetPage = currentPage;}targetValue = http://www.kingceram.com/post/point * targetPage;speed = 0f;turnPage = true;}}
区间的相关计算可以通过画一张图并拖动 , 观察它值的变化来理解 。