Unity ScrollView實(shí)現(xiàn)自動(dòng)吸附效果
本文實(shí)例為大家分享了Unity ScrollView實(shí)現(xiàn)自動(dòng)吸附效果的具體代碼,供大家參考,具體內(nèi)容如下
一、效果演示
二、實(shí)現(xiàn)思路
通過使用UGUI的拖拽接口,在拖拽結(jié)束時(shí)比較當(dāng)前滑動(dòng)框的NormalizedPositon與每一頁的NormalizedPositon值,找到距離當(dāng)前拖拽結(jié)束位置最近的頁并緩慢滑動(dòng)過去
三、使用說明
——此功能腳本是對(duì)ScrollView的擴(kuò)展,所以必須添加UGUI提供的基礎(chǔ)Scroll View
——Content上必須添加GridLayoutGroup組件并添加所有列表中的項(xiàng)(不是動(dòng)態(tài)添加),只是為了方便滿足布局需求(我在代碼中對(duì)startCorner、startAxis、childAlignment和constraintCount進(jìn)行了限制,不需要對(duì)其設(shè)置)
——不能添加Content Size Fitter組件
——測(cè)試出適合的視為滑動(dòng)一頁的距離和視為滑動(dòng)多頁的距離數(shù)值并填入即可
四、完整代碼
將AutoAdsorbScrollView腳本掛載到ScrollView上
using UnityEngine; using UnityEngine.UI; using UnityEngine.EventSystems; /// <summary> /// 自動(dòng)吸附的滑動(dòng)列表 /// </summary> public class AutoAdsorbScrollView : MonoBehaviour, IBeginDragHandler, IEndDragHandler { private ScrollRect scrollRect;//滑動(dòng)框組件 private RectTransform content;//滑動(dòng)框的Content private GridLayoutGroup layout;//布局組件 private int totalPage; //總頁數(shù) private int curPage; //當(dāng)前頁的下標(biāo) private float[] eachPageNUPos; //每頁的NormalizedPositon的值 private float targetNUPos; //目標(biāo)頁的NormalizedPositon的值 private Vector2 beginMousePos; //鼠標(biāo)開始按下的位置 private Vector2 endMousePos; //鼠標(biāo)結(jié)束按下的位置 private bool isDrag; //是否在拖拽 [Header("是否可以滑動(dòng)多頁")] public bool sliderMultPage; [Header("視為滑動(dòng)一頁的距離")] [Space(25)] public float sliderOnePageDis; [Header("視為滑動(dòng)多頁的距離")] public float sliderMultPageDis; [Header("緩動(dòng)到目標(biāo)頁的持續(xù)時(shí)間")] public float duration; #region Init private void Awake() { scrollRect = GetComponent<ScrollRect>(); content = scrollRect.content; layout = content.GetComponent<GridLayoutGroup>(); Init();//初始化 } /// <summary> /// 初始化 /// </summary> private void Init() { totalPage = content.childCount; SetContentSize();//設(shè)置Content大小 CalcEachPageNUPos();//計(jì)算每一頁的NormalizedPositon值 SetLayout();//設(shè)置布局 } /// <summary> /// 設(shè)置Content大小 /// </summary> private void SetContentSize() { content.sizeDelta = new Vector2 ( layout.padding.right + layout.padding.left + (totalPage - 1) * (layout.cellSize.x + layout.spacing.x) - layout.spacing.x, content.sizeDelta.y ); ; } /// <summary> /// 計(jì)算每一頁的NormalizedPositon值 /// </summary> private void CalcEachPageNUPos() { float tempNUPos = 0; eachPageNUPos = new float[totalPage]; for (int i = 0; i < totalPage; i++) { eachPageNUPos[i] = tempNUPos; tempNUPos += 1f / (totalPage - 1); } } /// <summary> /// 設(shè)置布局 /// </summary> private void SetLayout() { scrollRect.horizontal = true; scrollRect.vertical = false; layout.padding.right = layout.padding.left; layout.startCorner = GridLayoutGroup.Corner.UpperLeft; layout.childAlignment = TextAnchor.MiddleCenter; layout.constraintCount = 1; } #endregion #region Main /// <summary> /// 拖拽開始 /// </summary> public void OnBeginDrag(PointerEventData eventData) { isDrag = true; beginMousePos = Input.mousePosition; } /// <summary> /// 拖拽結(jié)束 /// </summary> /// <param name="eventData"></param> public void OnEndDrag(PointerEventData eventData) { isDrag = false; coe = 0; endMousePos = Input.mousePosition; Vector2 offset = endMousePos - beginMousePos; Debug.Log("滑動(dòng)距離為:" + offset); if (sliderMultPage) { //單頁滑動(dòng) if (Mathf.Abs(offset.x) >= sliderOnePageDis && Mathf.Abs(offset.x) < sliderMultPageDis) { float tempHorizontalNUPos = scrollRect.horizontalNormalizedPosition; FindNearlyPage(tempHorizontalNUPos); } //多頁滑動(dòng) else if (Mathf.Abs(offset.x) >= sliderMultPageDis) { if (offset.x > 0) { curPage = 0; } else if (offset.x < 0) { curPage = totalPage - 1; } } } else { //單頁滑動(dòng) if (Mathf.Abs(offset.x) >= sliderOnePageDis) { float tempHorizontalNUPos = scrollRect.horizontalNormalizedPosition; FindNearlyPage(tempHorizontalNUPos); } } targetNUPos = eachPageNUPos[curPage]; } private float coe;//比例系數(shù) private void Update() { if (isDrag) { return; } coe += Time.deltaTime / duration; scrollRect.horizontalNormalizedPosition = Mathf.Lerp(scrollRect.horizontalNormalizedPosition, targetNUPos, coe); } #endregion #region Tool /// <summary> /// 尋找距離當(dāng)前NormalizedPositon最近的頁 /// </summary> private void FindNearlyPage(float tempHorizontalNUPos) { float minOffset = Mathf.Abs(eachPageNUPos[0] - tempHorizontalNUPos); for (int i = 0; i < totalPage; i++) { float tempHorizontalOffset = Mathf.Abs(eachPageNUPos[i] - tempHorizontalNUPos); if (tempHorizontalOffset <= minOffset) { minOffset = tempHorizontalOffset; curPage = i; } } } #endregion }
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
C#實(shí)現(xiàn)文件與二進(jìn)制互轉(zhuǎn)并存入數(shù)據(jù)庫
這篇文章主要介紹了C#實(shí)現(xiàn)文件與二進(jìn)制互轉(zhuǎn)并存入數(shù)據(jù)庫,本文直接給出代碼實(shí)例,代碼中包含詳細(xì)注釋,需要的朋友可以參考下2015-06-06c# openxml 刪除xlsx、xls的外鏈?zhǔn)纠a
要?jiǎng)h除一個(gè) Excel 文件(.xlsx)中的外部鏈接(external links),你可以使用 OpenXML SDK,本文演示如何使用 OpenXML SDK 刪除外部鏈接,感興趣的朋友一起看看吧2024-01-01比較2個(gè)datatable內(nèi)容是否相同的方法
這篇文章主要介紹了比較2個(gè)datatable內(nèi)容是否相同的方法,大家參考使用吧2014-01-01c#只讀字段和常量的區(qū)別,以及靜態(tài)構(gòu)造函數(shù)的使用實(shí)例
這篇文章主要介紹了c#只讀字段和常量的區(qū)別,以及靜態(tài)構(gòu)造函數(shù)的使用實(shí)例,有需要的朋友可以參考一下2013-12-12C#實(shí)現(xiàn)批量更改文件名稱大小寫或擴(kuò)展名
這篇文章主要為大家詳細(xì)介紹了如何利用C#實(shí)現(xiàn)批量更改文件名稱大小寫或擴(kuò)展名的功能,文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)C#有一定的幫助,感興趣的小伙伴可以跟隨小編一起了解一下2022-12-12