Use the Toggle to switch to a different page in Unity

[目的]
於Unity中運用Toggle按鈕,讓群組物件進行切換,這UI呈現方式是很常會使用到的效果之一,以下解釋製作方式。
[場景物件]
於場景中準備被控制的物件群組、Toggle按鈕、可滑動區域的範圍Sroll Panel,
這邊的步驟就是像製作Scroll Veiw組件的概念,可參考前一篇的製作步驟:
http://3.112.19.130/2020/10/30/customize-scrollable-list-in-unity/

[方法]
在物件Scroll Panel上創建一個新的Script,命名為LevelScroll,則可開始進入寫腳本的部分,以下腳本會分為三階段:

第一階段-主要目的是取得群組物件水平座標,並運用座標來控制群組物件顯示在第幾頁。以下依序號碼解釋程式所代表的意思:
1.首先定義一個scroll Rect,並記得在程式最上方一定要加上
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;程式才會正常運作。
2.運用偵測在移動物件時的起始點與終點的function,來取得座標點。
3.在Start開始中,加入在場景上取得 scroll rect 組件。

4.取得群組物件水平位置的座標
這邊設定為群組物件一排12個,且運用3個Toggle來做之間的切換,因此將其分為三群組,也就是需取出3個水平位置點的數值。

為了要取出3個水平位置點的數值,程式中,在拖動物件終點時,設定posX為取得拖曳結尾水平座標的點,主要目標就是用座標來定義位置 。

按下Play,即可在console中讀取到3個水平終點座標 ,我們就是要用這3組數字來偵測目前要顯示第幾個群組。

5.用位置座標判斷要停留在哪一群組中。
接下來在程式中新增定義pageArray,Array裡面就是會放置第一頁-0.07f的位置、第二頁0.52f的位置 、 第三頁1.00f的位置,(這三個數值就是由前一步驟posX取得出來的水平座標)

運用差值來做判斷,當結尾拖曳的位置,越接近pageArray的位置點時,就會以靠近的頁面為主,以下分別認識一下程式碼所代表的意思:
a.預設起始頁碼為0
b.使用offset並用絕對值的方式,將3個點值的座標與當前座標,做差值的運算。
c.運用for迴圈,來控制跳至第幾頁,(也就是控制要跳至哪個座標點: -0.07f(第一頁), 0.52f(第二頁), 1.00f(第三頁))。
d.設定offsetTemp 為-0.07f, 0.52f, 1.00f這三點值其中之一與當下取得到的posX的點值相互相減,來判斷之間距離有多近。
e.如果得到的值小於取得的位置時,就實現跳頁至距離Array點最近的位置,如:座標靠近-0.07f的位置,就跳至-0.07f那一頁,若靠近0.52f時,則會跳至下一頁。)

按下Play,看第一階段結果:

第二階段-截至第一階段步驟,可以產生三段落的群組物件移動,但這中間,會發現移動間是直接跳轉並無過場,第二階段則是來增加過場效果,讓頁面切換間更為順暢。
1.增加定義一組目標點targetHorizontalPosition = 0,以及smoothing速度,並把for迴圈中取得最後水平點值改寫成targetHorizontalPosition = pageArray[index]; 並在update中增加Lerp程式,這段就是可以將第一個數值慢慢的變換為第二數值,也就是增加滑動間的動態效果。

2.因為這段過場動態是寫在update之中,所以程式會每一個frame都在偵測,其實是很吃資源的,因此要在update之中增加一段判斷式。增加定義isDrag,開始預設為false,當物件開始移動時為true,結束時為false,因此當 isDrag 等於false時,才會執行過場動態的程式。

按下Play,看第二階段結果:

第三階段-串接Toggle與頁面,當按下第N個Toggle,頁面則會跳轉至第N頁
1.用if方式設定,當toggle為isON時,則跳轉至某一頁,pageArray[0]為第一頁、 pageArray [1]為第二頁、 pageArray [2]為第三頁

2.回到場景上,由於要讓toggle來監聽 ScrollPanel底下 Level Scroll程式,所以要將 ScrollPanel 拖曳至toggle on value changed 之中,並於後方選擇LevelScroll>TogglePage1,3個Toggle皆需依序設定。

3.以上步驟完成了點選Toggle跳轉頁面的效果,現在需反過來,當滑動上方群組物件, 下方Toggle 狀態會跟著on或off。
首先,需增加定義toggleArray,並在結束Drag之後,把對應到的Toggle isOn變為True。

回到Unity場景,把剛定義的陣列,將3個toggle按鈕分別拖曳至欄位中。最後播放看看就可以看到拖曳上方物件群組,下方Toggle狀態也會跟著改變。

按下Play,看第三階段結果:

完整程式碼:

using JetBrains.Annotations;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class LevelScroll : MonoBehaviour, IBeginDragHandler, IEndDragHandler
{
    private ScrollRect scrollRect;//(1)1.定義一個scroll rect
    private float[] pageArray = new float[] { -0.07f, 0.52f, 1.00f }; 
    private float targetHorizontalPosition = 0;
    public float smoothing = 5;
    private bool isDraging = false;
    public Toggle[] toggleArray;
    void Start()
    {
        scrollRect = GetComponent<ScrollRect>();
    }
    void Update()
    {
        if (isDraging == false) 
        {
            scrollRect.horizontalNormalizedPosition = Mathf.Lerp(scrollRect.horizontalNormalizedPosition, targetHorizontalPosition, Time.deltaTime * smoothing);
        }        
    }
    public void OnBeginDrag(PointerEventData eventData) 
    {
        isDraging = true; 
    }

    public void OnEndDrag(PointerEventData eventData)
    {  isDraging = false;
        float posX = scrollRect.horizontalNormalizedPosition;  

        
        int index = 0;
        float offset = Math.Abs(pageArray[index] - posX);

        for (int i = 1; i < pageArray.Length; i++)
        {
            float offsetTemp = Math.Abs(pageArray[i] - posX); 
            if (offsetTemp < offset)  
            {
                index = i;
                offset = offsetTemp;
            }           
            targetHorizontalPosition  = pageArray[index];
            toggleArray[index].isOn = true;
        }
        print(posX);
    }

    public void TurnToPage1(bool isOn)
    {
        if (isOn)
        {targetHorizontalPosition = pageArray[0];}
    }
    public void TurnToPage2(bool isOn)
    {
        if (isOn)
        {targetHorizontalPosition = pageArray[1];}
    }

    public void TurnToPage3(bool isOn)
    {
        if (isOn)
        {targetHorizontalPosition = pageArray[2];}
    }
}

[小結]
以上分三階段達到運用toggle按鈕來控制頁面物件的效果,希望藉由其中先了解一些程式的邏輯與使用方式,這樣下次遇到類似的應用,要直接改寫程式也可以知道該如何改寫及運用。

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *