管理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呼叫到不必要的動作。
留言
張貼留言