Unity3D UGUI:UI组件及GameObject的事件监听系统

Unity新的UI系统的监听事件的用法有很多种,在UGUI刚出来的时候,网上也搜到过很多种用法,今天我就把这几种方法整理一下,分享给大家。

首先,是第一种方法,也是最直接简单粗暴的方法,但是这种方法只能在UI系统上使用,就是直接在UI组件上绑定事件,这个效率是最高的,但也是最麻烦的。要一个一个的去拖拽脚本到组件上。这个方法不光是Button组件,其他组件也会可以使用,比如InputField等。

第二种方法也是比较简单粗暴的,但是相对事件功能上要强大的多,也不依赖组件本身,也可以使用在非UI的GameObject上,这种方法如果用在非UI的物体上,需要在主相机上添加一个PhysicRaycaster组件才能使用。

第三种方法就是用代码动态的给组件加监听事件,这种方法其实和第一种原理是一样的。都是利用组件本身的事件接口去实现相应事件的方法,只不过是用代码实现的动态添加的事件监听。

下面是放个按钮的添加监听事件的方法,其中一个是带参数的添加方法。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class Test : MonoBehaviour
{
    Button btn1;
    Button btn2;
    // Use this for initialization
    void Start()
    {
        btn1 = GetComponent<Button>();
        btn1.onClick.AddListener(OnClick1);
        btn2 = GetComponent<Button>();
        btn2.onClick.AddListener(delegate () { OnClick2(btn2.gameObject); });
    }

    // Update is called once per frame
    void Update()
    {

    }
    public void OnClick1()
    {
        Debug.Log("Click");
    }
    public void OnClick2(GameObject go)
    {
        Debug.Log(go);
    }
}

第四种方法是和第二种方法的原理是一样的,和第三种方法的实现方式是一样的,在这里也就不多说了,下面直接放上代码。下面代码是用拓展的方式写的,如果单独用可以自行提取相应代码。

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.EventSystems;
using UnityEngine.UI;

public static class Develop
{
    public static void AddEventTrigger(this GameObject obj, EventTriggerType eventType, UnityAction<BaseEventData> myFunction)
    {
        EventTrigger eventTrigger = obj.GetComponent<EventTrigger>();
        if (eventTrigger == null)
        {
            eventTrigger = obj.AddComponent<EventTrigger>();
            eventTrigger.triggers = new List<EventTrigger.Entry>();
        }

        UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(myFunction);

        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventType;
        entry.callback.AddListener(callback);
        eventTrigger.triggers.Add(entry);
    }
    public static void RemoveEventTrigger(this GameObject obj)
    {
        EventTrigger eventTrigger = obj.GetComponent<EventTrigger>();
        if (eventTrigger == null)
        {
            return;
        }
        eventTrigger.triggers.Clear();
    }
    public static void AddEventTrigger(this Image obj, EventTriggerType eventType, UnityAction<BaseEventData> myFunction)
    {
        EventTrigger eventTrigger = obj.GetComponent<EventTrigger>();
        if (eventTrigger == null)
        {
            eventTrigger = obj.gameObject.AddComponent<EventTrigger>();
            eventTrigger.triggers = new List<EventTrigger.Entry>();
        }

        UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(myFunction);

        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventType;
        entry.callback.AddListener(callback);
        eventTrigger.triggers.Add(entry);
    }
    public static void RemoveEventTrigger(this Image obj)
    {
        EventTrigger eventTrigger = obj.gameObject.GetComponent<EventTrigger>();
        if (eventTrigger == null)
        {
            return;
        }
        eventTrigger.triggers.Clear();
    }
    public static void AddEventTrigger(this RawImage obj, EventTriggerType eventType, UnityAction<BaseEventData> myFunction)
    {
        EventTrigger eventTrigger = obj.GetComponent<EventTrigger>();
        if (eventTrigger == null)
        {
            eventTrigger = obj.gameObject.AddComponent<EventTrigger>();
            eventTrigger.triggers = new List<EventTrigger.Entry>();
        }

        UnityAction<BaseEventData> callback = new UnityAction<BaseEventData>(myFunction);

        EventTrigger.Entry entry = new EventTrigger.Entry();
        entry.eventID = eventType;
        entry.callback.AddListener(callback);
        eventTrigger.triggers.Add(entry);
    }
    public static void RemoveEventTrigger(this RawImage obj)
    {
        EventTrigger eventTrigger = obj.gameObject.GetComponent<EventTrigger>();
        if (eventTrigger == null)
        {
            return;
        }
        eventTrigger.triggers.Clear();
    }
}

最后一种方法,是根据NGUI的UIEventListener衍生出来的,用起来也是比较方便的,这个方法是在雨松大大的博客里看到的,我做了一写整理和修改。把一些常用的事件和相应的参数调整了一下,并且可以用在非UI的物体上。

using UnityEngine;
using UnityEngine.EventSystems;
public class UIEventListener : EventTrigger
{
    public delegate void VoidDelegate(GameObject go);
    public delegate void VectorDelegate(GameObject go, Vector2 screenPosition);
    public delegate void BoolDelegate(GameObject go, bool value);
    public VoidDelegate onClick;
    public VoidDelegate onDown;
    public VoidDelegate onUp;
    public BoolDelegate onHover;
    public VectorDelegate onBeginDrag;
    public VectorDelegate onDrag;
    public VectorDelegate onEndDrag;

    static public UIEventListener Get(GameObject go)
    {
        PhysicsRaycaster raycaster = Camera.main.gameObject.GetComponent<PhysicsRaycaster>();
        if (raycaster == null) raycaster = Camera.main.gameObject.AddComponent<PhysicsRaycaster>();
        UIEventListener listener = go.GetComponent<UIEventListener>();
        if (listener == null) listener = go.AddComponent<UIEventListener>();
        return listener;
    }
    public override void OnPointerClick(PointerEventData eventData)
    {
        if (onClick != null) onClick.Invoke(gameObject);
    }
    public override void OnPointerDown(PointerEventData eventData)
    {
        if (onDown != null) onDown.Invoke(gameObject);
    }
    public override void OnPointerUp(PointerEventData eventData)
    {
        if (onUp != null) onUp.Invoke(gameObject);
    }
    public override void OnPointerEnter(PointerEventData eventData)
    {
        if (onHover != null) onHover.Invoke(gameObject, true);
    }
    public override void OnPointerExit(PointerEventData eventData)
    {
        if (onHover != null) onHover.Invoke(gameObject, false);
    }
    public override void OnBeginDrag(PointerEventData eventData)
    {
        Vector2 position;
        Canvas canvas = FindObjectOfType<Canvas>();
        RectTransform rect = canvas.GetComponent<RectTransform>();
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, eventData.position, canvas.worldCamera, out position))
        {
            if (onBeginDrag != null) onBeginDrag.Invoke(gameObject, position);
        }
    }
    public override void OnDrag(PointerEventData eventData)
    {
        Vector2 position;
        Canvas canvas = FindObjectOfType<Canvas>();
        RectTransform rect = canvas.GetComponent<RectTransform>();
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, eventData.position, canvas.worldCamera, out position))
        {
            if (onDrag != null) onDrag.Invoke(gameObject, position);
        }
    }
    public override void OnEndDrag(PointerEventData eventData)
    {
        Vector2 position;
        Canvas canvas = FindObjectOfType<Canvas>();
        RectTransform rect = canvas.GetComponent<RectTransform>();
        if (RectTransformUtility.ScreenPointToLocalPointInRectangle(rect, eventData.position, canvas.worldCamera, out position))
        {
            if (onEndDrag != null) onEndDrag.Invoke(gameObject, position);
        }
    }
}

You May Also Like

About the Author: 大腿Plus

发表评论