【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:蒋志杰

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值