【Unity3d】介紹兩個實用的UI按鈕小工具
阿新 • • 發佈:2019-01-03
平面和遊戲開發中會需要很多的按鈕,UGUI的按鈕使用UnityEvent的話只能響應點選事件,而且如果需要空白按鈕設定Image的alpha值的話有時候會影響fade動畫。這裡介紹兩個工具,一個用來做空白按鈕或者按鈕遮罩,不會佔用額外的drawcall。另一個是繼承EventTrigger的工具類,可是實現按鈕響應按下,擡起,拖動等等事件。
1、空白按鈕
或者可以說是一個遮罩,首先建立一個繼承MaskableGraphic的類,然後重寫OnPopulateMesh函式,不繪製任何東西。
public class EmptyButton : MaskableGraphic
{
protected EmptyButton()
{
useLegacyMeshGeneration = false;
}
protected override void OnPopulateMesh(VertexHelper vh)
{
vh.Clear();
}
}
然後只需要把這個指令碼掛載到物體上,並新增Button控制元件就可以實現空白按鈕的功能了。如果我們只是需要一個遮罩的話,直接掛在這個指令碼,不新增Button控制元件就可以了。
2、EventTriggerListener
首先建立一個繼承EventTrigger的類,用來監聽Untiy支援的EventTrigger事件,具體支援的事件可以參考 Unity官方文件。這裡參考了宣雨鬆的UGUI研究院之控制元件以及按鈕的監聽事件系統(五)一文。先定義一個 delegate來監聽事件。需要監聽的事件可以根據需要進行拓展。
public delegate void VoidDelegate(GameObject go);
public VoidDelegate onClick;
定義一個靜態的Get方法來獲取我們的監聽器:
static public EventTriggerListener Get(GameObject go)
{
EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
if (listener == null)
listener = go.AddComponent<EventTriggerListener>();
return listener;
}
實現onClick事件:
public override void OnPointerClick(PointerEventData eventData)
{
if (onClick != null)
onClick(gameObject);
}
在另一個行為指令碼中對我們需要的UI進行監聽,這裡注意UI需要可以檢測射線碰撞,比如Image控制元件或者上面提到的EmptyButton,並把Raycast Target勾上。
void Awake()
{
EventTriggerListener.Get(gameObject).onClick = OnClick;
}
public OnClick(GameObject go)
{
if(go == gameObject)
{
// your code
}
}
這裡給出一個常用事件監聽的EventTriggerListener:
//====================================================================================//
// //
// 可代替ugui的button實現更為複雜的按鈕功能 //
// 除給出的delegate外還可以自行新增其他的事件 //
// 參考文件:https://docs.unity3d.com/460/Documentation/Manual/SupportedEvents.html //
// 參考實現:http://www.xuanyusong.com/archives/3325 //
// //
//====================================================================================//
using UnityEngine;
using UnityEngine.EventSystems;
public class EventTriggerListener : EventTrigger
{
public delegate void VoidDelegate(GameObject go);
public VoidDelegate onEnter;
public VoidDelegate onExit;
public VoidDelegate onDown;
public VoidDelegate onUp;
public VoidDelegate onClick;
public VoidDelegate onBeginDrag;
public VoidDelegate onDrag;
public VoidDelegate onEndDrag;
// 新增需要的事件
static public EventTriggerListener Get(GameObject go)
{
EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
if (listener == null)
listener = go.AddComponent<EventTriggerListener>();
return listener;
}
public override void OnPointerEnter(PointerEventData eventData)
{
if (onEnter != null)
onEnter(gameObject);
}
public override void OnPointerExit(PointerEventData eventData)
{
if (onExit != null)
onExit(gameObject);
}
public override void OnPointerDown(PointerEventData eventData)
{
if (onDown != null)
onDown(gameObject);
}
public override void OnPointerUp(PointerEventData eventData)
{
if (onUp != null)
onUp(gameObject);
}
public override void OnPointerClick(PointerEventData eventData)
{
if (onClick != null)
onClick(gameObject);
}
public override void OnBeginDrag(PointerEventData eventData)
{
if (onBeginDrag != null)
onBeginDrag(gameObject);
}
public override void OnDrag(PointerEventData eventData)
{
if (onDrag != null)
onDrag(gameObject);
}
public override void OnEndDrag(PointerEventData eventData)
{
if (onEndDrag != null)
onEndDrag(gameObject);
}
}
By:蔣志傑