[目的]
於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按鈕來控制頁面物件的效果,希望藉由其中先了解一些程式的邏輯與使用方式,這樣下次遇到類似的應用,要直接改寫程式也可以知道該如何改寫及運用。