首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

NGUI 實現滑動翻頁效果:從觸控偵測到 Tween 動畫完整實作

     編輯:關於C語言

前言

NGUI 作為 Unity 早期主流 UI 框架,許多存量專案仍在維護中。本文提供一份完整、可直接落地的 NGUI 滑動翻頁實作,涵蓋觸控偵測、閾值判斷、Tween 位移動畫與頁碼狀態機,適合快速接手舊專案或學習 NGUI 事件機制的開發者。

核心架構

  • PageView 掛載在頁面容器(包含所有頁面的父物件)上。
  • 每頁寬度固定(PAGE_WIDTH = 2048),總頁數 ITEM_NUM。
  • 利用 UIEventListener 監聽 OnPress 事件,記錄按下/抬起座標。
  • 透過 TweenPosition 執行 EaseInOut 緩動動畫,動畫完成回調更新頁碼狀態。

關鍵參數說明

常數預設值用途
ITEM_NUM2總頁數
PAGE_WIDTH2048單頁寬度(像素)
DRAG_SPEED0.5f翻頁動畫時長(秒)
DRAG_OFFECT30觸發翻頁的最小水平位移閾值

完整腳本:PageView.cs

using UnityEngine;
using System.Collections;

public class PageView : MonoBehaviour
{
    const int ITEM_NUM = 2;
    const int PAGE_WIDTH = 2048;
    const float DRAG_SPEED = 0.5f;
    const int DRAG_OFFECT = 30;

    float beganX, beganY;
    int curIndex = 1;
    bool isPlay = false, isPress = false;
    bool isPageFoot = false, isHomePage = true;
    string left = "left", right = "right";
    GameObject[] Item_Objects;

    void Start() => Init();

    void Init()
    {
        Item_Objects = new GameObject[ITEM_NUM];
        for (int i = 1; i <= ITEM_NUM; ++i)
        {
            Transform trans = transform.Find("item" + i);
            if (trans != null)
            {
                GameObject spr = trans.Find("Background").gameObject;
                spr.AddComponent();
                UIEventListener.Get(spr).onPress = OnPressEvent;
                Item_Objects[i - 1] = trans.gameObject;
            }
        }
    }

    void OnPressEvent(GameObject obj, bool isDown)
    {
        if (isDown)
        {
            beganX = UICamera.lastTouchPosition.x;
            beganY = UICamera.lastTouchPosition.y;
            isPress = true;
        }
        else
        {
            float endX = UICamera.lastTouchPosition.x;
            float endY = UICamera.lastTouchPosition.y;

            if (isPress && !isPlay)
            {
                float delta = endX - beganX;
                if (delta > DRAG_OFFECT && !isHomePage) RightDrag();
                else if (delta < -DRAG_OFFECT && !isPageFoot) LeftDrag();
            }
            isPress = false;
        }
    }

    void LeftDrag()
    {
        isPlay = true;
        float x = transform.localPosition.x - PAGE_WIDTH;
        var tween = TweenPosition.Begin(gameObject, DRAG_SPEED, new Vector3(x, 0, 0));
        tween.method = UITweener.Method.EaseInOut;
        tween.callWhenFinished = "callback";
        tween.name = left;
        tween.Reset();
    }

    void RightDrag()
    {
        isPlay = true;
        float x = transform.localPosition.x + PAGE_WIDTH;
        var tween = TweenPosition.Begin(gameObject, DRAG_SPEED, new Vector3(x, 0, 0));
        tween.method = UITweener.Method.EaseInOut;
        tween.callWhenFinished = "callback";
        tween.name = right;
        tween.Reset();
    }

    void callback(UITweener tween)
    {
        isPlay = false;
        if (tween.name == left) curIndex++;
        else if (tween.name == right) curIndex--;

        isHomePage = (curIndex == 1);
        isPageFoot = (curIndex == ITEM_NUM);
    }
}

實作細節與避坑指南

1. 事件掛載對象

範例掛載在各頁面的 Background 物件上,確保其有 BoxCollider 且屬於 UI Layer,否則 UICamera 無法偵測觸控。

2. 坐標系統

NGUI 使用 UICamera.lastTouchPosition 取得螢幕座標(非世界座標),直接相減即可得到水平位移,無需轉換。

3. 動畫衝突防護

isPlay 標記防止動畫播放期間重複觸發;isPress 確保只有完整的 Press→Release 才判定翻頁。

4. 邊界保護

isHomePage / isPageFoot 防止超出首尾頁;若需循環翻頁,可在回調中重排子物件位置並重置 curIndex。

5. 多頁支援

將 ITEM_NUM、PAGE_WIDTH 改為 public 或從配置讀取,即可支援任意頁數。

進階擴展建議

  • 指示器同步:在 callback 中發送事件或直接操作底部 Dot 圖集切換。
  • 慣性滑動:引入 SpringPanel 或自行實作速度衰減,配合 OnDrag 即時位移。
  • 編輯器工具:撰寫 ContextMenu 一鍵生成頁面預製體與自動計算寬度。

總結

NGUI 翻頁的核心在於「觸控位移判斷 + Tween 位移動畫 + 狀態機同步」。本範例邏輯清晰、耦合度低,直接拖入專案即可使用。若專案已遷移至 UGUI,建議參考上一篇 ScrollRect 方案;若維護舊專案,此實作足以應對大多數翻頁需求。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved