Unity UGUI按頁滑動

實現UGUI滾動滾動視圖下 滑動翻頁,其中主要是Mathf.Lerp(start,end,time)插值計算(對於插值計算不了解的話 可以看看unity官網介紹https://docs.unity3d.com/ScriptReference/Mathf.Lerp.html)

代碼如下:

using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

enum Drag_State
{
    None,
    Draging,
    Dragend
}
public class LerpTest : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    private float smooting = 5;
    public GameObject scroll_content;
    private ScrollRect scroll_rect;
    private Drag_State state = Drag_State.None;
    private float target_hnp = 0.0f;

    private int page_index = 0;

    private float sensitivity = 0.1f;

    void Awake()
    {
        scroll_rect = transform.GetComponent<ScrollRect>();
    }
    void Update()
    {
        if (state == Drag_State.Dragend)
        {   
            if (Math.Abs(target_hnp - scroll_rect.horizontalNormalizedPosition)<0.01f)//已經很接近目標值了  就不用再繼續勻速變化了 直接設置就行
            {
                scroll_rect.horizontalNormalizedPosition = target_hnp;
                state = Drag_State.None;
                return;
            }
            scroll_rect.horizontalNormalizedPosition = Mathf.Lerp(scroll_rect.horizontalNormalizedPosition, target_hnp, Time.deltaTime * smooting);
        }           
    }
    void OnGUI()
    {
        if(GUI.Button(new Rect(100, 100, 150, 50), "left"))
        {
            SelectPage(page_index - 1);
        }

        if (GUI.Button(new Rect(400, 100, 150, 50), "right"))
        {
            SelectPage(page_index + 1);
        }
    }

    public void SelectPage(int index)
    {
        int page_count = scroll_content.transform.childCount;
        if (page_count < 2)
        {
            state = Drag_State.None;
            return;
        }


        state = Drag_State.Dragend;
        
        page_index = index;
        if (page_index >= page_count)
        {
            page_index = page_count - 1;
        }

        if (page_index < 0)
        {
            page_index = 0;
        }

        float page_value = 1.0f / (page_count - 1);
        target_hnp = page_index * page_value;
    }

    //
    public void OnBeginDrag(PointerEventData eventData)
    {
        state = Drag_State.Draging;
    }

    //
    public void OnEndDrag(PointerEventData eventData)
    {
        int page_count = scroll_content.transform.childCount;
        if(page_count < 2)
        {
            state = Drag_State.None;
            return;
        }
        state = Drag_State.Dragend;
        float current_hnp = scroll_rect.horizontalNormalizedPosition;
        
        float page_value = 1.0f / (page_count - 1);//每一頁所佔的值
        float last_hnp = page_index * page_value;//頁碼*每一頁所佔的值 計算出拖拽之前的horizontalNormalizedPosition

        for (int index = 0; index < page_count; index++)
        {
            //比較當前horizontalNormalizedPosition和拖拽之前horizontalNormalizedPosition 判斷拖拽方向
            //根據拖拽方向以及敏感值 就可以計算出每一頁在拖拽時horizontalNormalizedPosition值所在區間的左右端點
            //然後判斷當前的horizontalNormalizedPosition在哪一頁的區間內  就滾動到哪一頁
            float pre_value = current_hnp > last_hnp ? (index - 1) * page_value + sensitivity * page_value : index * page_value - sensitivity * page_value;
            float next_value = current_hnp > last_hnp ? index * page_value + sensitivity * page_value:(index + 1) * page_value - sensitivity * page_value;
            if (pre_value < current_hnp && current_hnp < next_value)
            {
                page_index = index;
                target_hnp = page_index * page_value;
                return;
            }
        }
    }
}

說明:

smooting : 滑動翻頁的速度

scroll_content :所有頁的父物體,主要是爲了獲取到底有多少頁,如果頁數是固定的話  GameObject就沒必要留着了

scroll_rect :ScrollRect 滾動視圖

state :拖拽狀態

target_hnp :拖拽結束後ScrollRect 的horizontalNormalizedPosition的目標值

page_index :當前頁碼

sensitivity : 敏感值,滑動時用來限定本頁的範圍

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章