2019-07-12
自定義事件面板是什么?
U3D中 一般實(shí)現(xiàn)點(diǎn)擊功能是通過添加Button組件的方式
如圖 可以看見 在這個(gè)面板的最下方有個(gè)名為 OnClick()的子面板 這就是自定義事件面板 我們可以在這里添加點(diǎn)擊事件 并且向其中拖入其它物體 然后選擇此物體中的任意腳本的公共方法
在Button被點(diǎn)擊時(shí) 就會調(diào)用在這個(gè)面板中添加的所有腳本方法 以此來實(shí)現(xiàn)點(diǎn)擊功能
那么 這個(gè)面板我可不可以給自己來用呢 或者 我可以讓自己的腳本里也出現(xiàn)這么方便的功能嗎?
答案是可以的 Button組件之所以可以實(shí)現(xiàn)這個(gè)功能 是因?yàn)榇私M件有一個(gè)內(nèi)部類:
ButtonClickedEvent
ButtonClickedEvent是什么?如何使用?
Button組件的源碼
namespace UnityEngine.UI
{
[AddComponentMenu("UI/Button", 30)]
public class Button : Selectable, IPointerClickHandler, IEventSystemHandler, ISubmitHandler
{
protected Button();
public ButtonClickedEvent onClick { get; set; }
public virtual void OnPointerClick(PointerEventData eventData);
public virtual void OnSubmit(BaseEventData eventData);
public class ButtonClickedEvent : UnityEvent
{
public ButtonClickedEvent();
}
}
}
注意這個(gè)onClick屬性
可以發(fā)現(xiàn) 所謂在ButtonClickedEvent其實(shí)就是我們在用代碼添加Button事件時(shí)使用的onClick變量
Button button = GetComponent<Button>();
button.onClick.AddListener(delegate { Debug.Log("點(diǎn)擊"); });
還要注意 ButtonClickedEvent 類是繼承自UnityEvent 而這個(gè)類才是實(shí)現(xiàn)事件List的主體 ButtonClickedEvent 只是一個(gè)繼承 沒有對父類做出任何修改 這里只是提一下
總之 目前看來 只要我們在自己的腳本將UnityEvent 設(shè)為公共變量 我們就可以擁有一個(gè)有添加事件功能的自定義面板了
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.Events;
using UnityEngine.EventSystems;
[AddComponentMenu("SelecterButton")]
public class SelecterButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler
{
private Image image;
private RectTransform rectTransform;
private SelecterGroup selecterGroup;
public Color normalColor = Color.white, highlightedColor = Color.white, selectedColor = Color.gray;
public bool isOn = true;
public UnityEvent onClick;
注意:需要引入 using UnityEngine.Events; 才可以使用UnityEvent 類
之后 只要使用UnityEvent.Invoke()方法 就會調(diào)用全部在這個(gè)類中注冊的方法
但是現(xiàn)在問題來了 應(yīng)該在哪里調(diào)用盲再?之所以要單獨(dú)把這個(gè)類取出來 就是為了自己來實(shí)現(xiàn)點(diǎn)擊 現(xiàn)在沒了Button組件 我要怎么接收點(diǎn)擊呢?
簡單的接收點(diǎn)擊事件的方法
答案 就在Button的代碼里 這個(gè)類實(shí)現(xiàn)了一個(gè)接口:IPointerClickHandler
類似的接口還有很多 都是和手勢有關(guān) 而IPointerClickHandler接口是專門接收點(diǎn)擊手勢的接口
按照Unity3D的事件系統(tǒng) 只要你在場景中加入了任何UI元素 就會自動生成一個(gè)名為EventSystem的物體 這個(gè)物體添加了EventSystem和StandaloneInputModule組件 它們一個(gè)管事件分發(fā) 一個(gè)管事件命名和接收 游戲正常的手勢輸入缺一不可
而只要有這個(gè)物體存在 只要是實(shí)現(xiàn)了事件接口的腳本(比如實(shí)現(xiàn)了IPointerClickHandler)都會調(diào)用對應(yīng)的實(shí)現(xiàn)方法(且有內(nèi)部判斷 只有點(diǎn)擊到物體本身才會調(diào)用) 以這種方式 我們可以接收到點(diǎn)擊了
實(shí)現(xiàn)接口:
public class SelecterButton : MonoBehaviour, IPointerEnterHandler, IPointerExitHandler, IPointerClickHandler{
//-- 其它代碼 --
//點(diǎn)擊事件實(shí)現(xiàn)
public void OnPointerClick(PointerEventData eventData)
{
Debug.Log("點(diǎn)擊");
//在這里調(diào)用UnityEvent.Invoke();
}
public void OnPointerEnter(PointerEventData eventData)
{
Debug.Log("鼠標(biāo)進(jìn)入");
}
public void OnPointerExit(PointerEventData eventData)
{
Debug.Log("鼠標(biāo)離開");
}
}
事件生效:
和UnityEvent.Invoke()結(jié)合 就可以實(shí)現(xiàn)自己的點(diǎn)擊 而不用依靠添加Button組件來實(shí)現(xiàn)了