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 : 敏感值,滑动时用来限定本页的范围

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