Unity實現(xiàn)ScrollView滑動吸附功能
本文實例為大家分享了Unity實現(xiàn)ScrollView滑動吸附的具體代碼,供大家參考,具體內(nèi)容如下
最近在做一個展示模塊的時候遇到了一個需要實現(xiàn)滑動窗口并且能固定吸附距離的需求,借助UGUI的ScrollView的API以及Dotween實現(xiàn)了這個功能。主要核心邏輯就是檢測Content節(jié)點的RectTransform的localPosX的移動距離然后繼承實現(xiàn)OnDrag幾個接口來完成拖動再松開自動吸附到具體的位置。具體效果如下

另外說一下有幾個ScrollView自帶的API需要設置一下,一個事Movement Type設置成Unrestricted,以及關閉Inertia,這樣才能關閉ScrollView自帶的最大距離移動控制不會導致在松手吸附過程中因為拖動距離大于了左右兩邊限制而最終的移動結(jié)束的坐標位置不對。

下面貼一下代碼,腳本直接附在Content物體上既可。
Tip:代碼里的450 225是一個子物體寬度的加上content的Space距離,我演示的工程師一個Image420的寬度 30的HorLayout Space,225則是這個距離/2,可以根據(jù)具體需求去改變由于只是為了出個DEMO就沒有寫成變量
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using DG.Tweening;
using DG.Tweening.Core.Easing;
using UnityEngine.Experimental.UIElements;
public class ScorllViewAutoHandler : MonoBehaviour, IEndDragHandler, IBeginDragHandler, IDragHandler
{
private GameObject Scroll;
private ScrollRect sc;
private float OriginPosX;
private float offsetX;
private int CurIndex;
private bool isDragging = false;
private bool TimerFlag = false;
private float Timer;
// Start is called before the first frame update
void Start()
{
CurIndex = 0;
Scroll = this.gameObject;
sc = Scroll.transform.parent.transform.parent.gameObject.GetComponent<ScrollRect>();
}
public void OnEndDrag(PointerEventData eventData)
{
int tempIndex=0;
sc.OnEndDrag(eventData);
offsetX = this.transform.localPosition.x - OriginPosX;
if (Mathf.Abs(offsetX) % 450 < 225)
{
tempIndex = (int)(Mathf.Abs(offsetX) / 450);
int _TempTargetIndex = 0;
if (offsetX <0)
{
_TempTargetIndex = CurIndex + tempIndex;
}
else
{
_TempTargetIndex = CurIndex - tempIndex;
}
if (_TempTargetIndex >= 0 && _TempTargetIndex <= Scroll.transform.childCount - 1)
{
_TempTargetIndex = _TempTargetIndex;
}
else if (_TempTargetIndex < 0)
{
_TempTargetIndex = 0;
}
else
{
_TempTargetIndex = Scroll.transform.childCount - 1;
}
Debug.LogError("本次位移目標" + _TempTargetIndex + "初始" + CurIndex);
this.transform.DOLocalMoveX(_TempTargetIndex*450, 0.5f).SetEase(Ease.OutBack);
}
else
{
tempIndex = (int)(Mathf.Abs(offsetX) / 450);
tempIndex += 1;
int _TempTargetIndex = 0;
if (offsetX < 0)
{
_TempTargetIndex = CurIndex + tempIndex;
}
else
{
_TempTargetIndex = CurIndex - tempIndex;
}
if (_TempTargetIndex >= 0 && _TempTargetIndex <= Scroll.transform.childCount - 1)
{
_TempTargetIndex = _TempTargetIndex;
}
else if (_TempTargetIndex < 0)
{
_TempTargetIndex = 0;
}
else
{
_TempTargetIndex = Scroll.transform.childCount - 1;
}
Debug.LogError("本次位移目標" + _TempTargetIndex + "初始" + CurIndex);
this.transform.DOLocalMoveX(_TempTargetIndex*450, 0.5f).SetEase(Ease.OutBack);
}
}
public void OnBeginDrag(PointerEventData eventData)
{
sc.OnBeginDrag(eventData);
OriginPosX = this.transform.localPosition.x;
CurIndex = (int)(Mathf.Abs(this.transform.localPosition.x) / 450);
offsetX = 0;
//當鼠標在A對象按下并開始拖拽時 A對象響應此事件
// 此事件在OnInitializePotentialDrag之后響應 OnDrag之前響應
//Debug.Log("OnBeginDrag " );
}
public void OnDrag(PointerEventData eventData)
{
sc.OnDrag(eventData);
//Debug.LogError("Dragging" );
}
}
以上就是本文的全部內(nèi)容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
c# 利用易福門振動模塊VSE002采集振動數(shù)據(jù)的方法
這篇文章主要介紹了c# 利用易福門振動模塊VSE002采集振動數(shù)據(jù)的方法,本文通過圖文實例相結(jié)合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-04-04
C#調(diào)用sql2000存儲過程方法小結(jié)
這篇文章主要介紹了C#調(diào)用sql2000存儲過程的方法,以實例形式分別對調(diào)用帶輸入?yún)?shù)及輸出參數(shù)的存儲過程進行了詳細分析,非常具有實用價值,需要的朋友可以參考下2014-10-10
Unity UGUI的LayoutElement布局元素組件介紹使用示例
這篇文章主要為大家介紹了Unity UGUI的LayoutElement布局元素組件介紹使用示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-07-07

