管理Unity GUI的按鈕點擊事件
或許有人跟我一樣不太喜歡Unity內建的Button。
除了操作步驟有點繁瑣之外,為了指派點擊事件的呼叫對象
還必須要將對應的函式宣告為public成員。
對於隱匿性來說總覺得不那麼恰當。
於是我另外寫了一個針對游標點擊事件的腳本用來解決上述的需求。
沒時間了快上 code!
在這個型別中,我們可以呼叫Init代入要掛載的點擊對象,
並且指派點擊事件發生之後的呼叫函式。
當掛載的物件發生點擊事件時,OnPointerClick函式將會被呼叫
之後再藉由pointerClicked呼叫委派的函式就可以了。
使用範例如下:
假使有一些特殊狀況無法藉由Index判斷對象,
並且想要快速取得對應按鈕事件的某個Image或者Text,
在呼叫Init函式的時候則可以另外儲存對象。
使用範例如下:
在上方的範例中,我順便加了一個鎖定操控的機制。
當任何按鈕被按下時,在canv底下的按鈕都會無法接收到游標事件,
直到UnlockOpration函式再次被呼叫為止。
目前為止改用UGUI系統已經開發過了幾個專案,
到現在都一直使用這一套方式來管理點擊的事件。
儲存Image與Text則是近期需求才擴增的,
這裡可以依照專案需求去增減儲存的物件。
若還要感應其他的游標事件如游標的滑入滑出,拖曳等等,
我比較偏向以類似的架構另外寫一個新的腳本,避免EventSystems呼叫到不必要的動作。
除了操作步驟有點繁瑣之外,為了指派點擊事件的呼叫對象
還必須要將對應的函式宣告為public成員。
對於隱匿性來說總覺得不那麼恰當。
於是我另外寫了一個針對游標點擊事件的腳本用來解決上述的需求。
沒時間了快上 code!
*************************************************
* Description
* 偵測UGUI物件的游標點擊事件
*
* Usage
* 呼叫Init並且代入掛載對象與游標事件的呼叫函式
* 在Init函式中可以指定索引
* 可以額外儲存單個Image與Text
**************************************************/
using System;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;
public class UGUIClickListener : MonoBehaviour, IPointerClickHandler
{
#region >> Fields & Properties
[SerializeField]
[Header("索引編號")]
int index;
public int Index
{
get { return index; }
}
[SerializeField]
[Header("圖像")]
Image image;
public Image Image
{
get { return image; }
}
[SerializeField]
[Header("文字")]
Text text;
public Text Text
{
get { return text; }
}
Action<UGUIClickListener> pointerClicked;
#endregion
/// <summary>
/// 將代入的物件添加Component,並且指派游標事件的呼叫函式
/// </summary>
/// <param name="go">要添加腳本的物件對象</param>
/// <param name="action">事件的呼叫對象</param>
/// <param name="id">設置編號索引</param>
public static UGUIClickListener Init(GameObject go, Action<UGUIClickListener> action, int id = 0)
{
UGUIClickListener listener = go.GetComponent<UGUIClickListener>();
if(listener == null)
{
listener = go.AddComponent<UGUIClickListener>();
}
listener.index = id;
listener.pointerClicked= action;
return listener;
}
/// <summary>
/// 儲存Image物件
/// </summary>
public UGUIClickListener SetImage(Image input)
{
image = input;
return this;
}
/// <summary>
/// 儲存Text物件
/// </summary>
public UGUIClickListener SetText(Text input)
{
text = input;
return this;
}
/// <summary>
/// IPointerClickHandler的介面實作,偵測游標對於掛載物件的Click事件
/// </summary>
public void OnPointerClick(PointerEventData data)
{
if(PointerClicked != null)
{
pointerClicked(this);
}
}
}
在這個型別中,我們可以呼叫Init代入要掛載的點擊對象,
並且指派點擊事件發生之後的呼叫函式。
當掛載的物件發生點擊事件時,OnPointerClick函式將會被呼叫
之後再藉由pointerClicked呼叫委派的函式就可以了。
使用範例如下:
using UnityEngine;
using UnityEngine.UI;
public class ButtonClickSample : MonoBehaviour
{
public Image[] buttons;
void Start() {
for(int i = 0; i < buttons.Length; i++) {
UGUIClickListener.Init(buttons[i].gameObject, ButtonClickEvent, i);
}
}
void ButtonClickEvent(UGUIClickListener ev) {
Debug.Log("Button Clicked: " + ev.Index);
}
}
假使有一些特殊狀況無法藉由Index判斷對象,
並且想要快速取得對應按鈕事件的某個Image或者Text,
在呼叫Init函式的時候則可以另外儲存對象。
使用範例如下:
using UnityEngine;
using UnityEngine.UI;
public class ButtonClickSample : MonoBehaviour
{
[SerializeField] CanvasGroup canv;
[SerializeField] Image[] buttons;
void Start() {
for(int i = 0; i < buttons.Length; i++) {
UGUIClickListener.Init(buttons[i].gameObject, ButtonClickEvent).SetImage(buttons[i]);
}
}
void ButtonClickEvent(UGUIClickListener ev) {
UnlockOpration(false);
ev.Image.color = Color.gray;
}
void UnlockOpration(bool enable = true) {
canv.blocksRaycasts = enable;
}
}
在上方的範例中,我順便加了一個鎖定操控的機制。
當任何按鈕被按下時,在canv底下的按鈕都會無法接收到游標事件,
直到UnlockOpration函式再次被呼叫為止。
目前為止改用UGUI系統已經開發過了幾個專案,
到現在都一直使用這一套方式來管理點擊的事件。
儲存Image與Text則是近期需求才擴增的,
這裡可以依照專案需求去增減儲存的物件。
若還要感應其他的游標事件如游標的滑入滑出,拖曳等等,
我比較偏向以類似的架構另外寫一個新的腳本,避免EventSystems呼叫到不必要的動作。


留言
張貼留言