1. 程式人生 > >【Unity3d】介紹兩個實用的UI按鈕小工具

【Unity3d】介紹兩個實用的UI按鈕小工具

平面和遊戲開發中會需要很多的按鈕,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:蔣志傑