UGUI 可视化创建以及关联事件很方便, 动态创建可以利用创建好的 Prefab 进行实例化, 只是在关联事件上有些复杂, 本文总结了几种给按钮绑定事件的关联方式.
1. 可视化创建及事件绑定 #
Step 1 : 通过 Hierarchy 面板创建 UI > Button
.
Step 2 : 创建一个脚本 TestClick.cs, 定义了一个 Click 的 public 方法.
Step 3 : 选中 Hierarchy 中的 Button, Add Component
Step 4 : 在 Button(Script)
Step 5 : Done.
TestClick.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestClick : MonoBehaviour {
public void Click(){
Debug.Log ("Button Clicked. TestClick.");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class TestClick : MonoBehaviour {
public void Click(){
Debug.Log ("Button Clicked. TestClick.");
}
}
2. 通过直接绑定脚本来绑定事件 #
Step 1 : 通过 Hierarchy 面板创建 UI > Button
.
Step 2 : 创建一个 ClickHandler.cs 脚本, 定义了一个私有方法 OnClick(), 并在 Start() 方法里为 Button 添加点击事件的监听,作为参数传入 OnClick 方法.
Step 3 : 将 ClickHandler 绑定在 Button 对象上.
Step 4 : Done.
ClickHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ClickHandler : MonoBehaviour {
void Start () {
Button btn = this.GetComponent<Button> ();
btn.onClick.AddListener (OnClick);
}
private void OnClick(){
Debug.Log ("Button Clicked. ClickHandler.");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ClickHandler : MonoBehaviour {
void Start () {
Button btn = this.GetComponent<Button> ();
btn.onClick.AddListener (OnClick);
}
private void OnClick(){
Debug.Log ("Button Clicked. ClickHandler.");
}
}
3. 通过 EventTrigger 实现按钮点击事件 #
UGUI 系统中 Button 默认只提供了 OnClick 的调用方法, 有时候我们还需要监听鼠标进入事件 (MouseIn) 和鼠标滑出事件 (MouseOut). 就需要借助 UI 系统中的 EventTrigger 脚本来实现.
Step 1 : 通过 Hierarchy 面板创建 UI > Button
.
Step 2 : 创建一个 EventTriggerHandler.cs 脚本, 利用 UnityEngine.EventSystems.EventTrigger 添加监听事件.
Step 3 : 绑定 EventTriggerHandler.cs 脚本到 Button 上.
Step 4 : Done.
EventTriggerHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
// 需要 EventTrigger 脚本的支援
[RequireComponent(typeof(UnityEngine.EventSystems.EventTrigger))]
public class EventTriggerHandler : MonoBehaviour {
// Use this for initialization
void Start () {
Button btn = this.GetComponent<Button> ();
EventTrigger trigger = btn.gameObject.GetComponent<EventTrigger> ();
EventTrigger.Entry entry = new EventTrigger.Entry ();
// 鼠标点击事件
entry.eventID = EventTriggerType.PointerClick;
// 鼠标进入事件 entry.eventID = EventTriggerType.PointerEnter;
// 鼠标滑出事件 entry.eventID = EventTriggerType.PointerExit;
entry.callback = new EventTrigger.TriggerEvent ();
entry.callback.AddListener (OnClick);
// entry.callback.AddListener (OnMouseEnter);
trigger.triggers.Add (entry);
}
private void OnClick(BaseEventData pointData){
Debug.Log ("Button Clicked. EventTrigger..");
}
private void OnMouseEnter(BaseEventData pointData){
Debug.Log ("Button Enter. EventTrigger..");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
// 需要 EventTrigger 脚本的支援
[RequireComponent(typeof(UnityEngine.EventSystems.EventTrigger))]
public class EventTriggerHandler : MonoBehaviour {
// Use this for initialization
void Start () {
Button btn = this.GetComponent<Button> ();
EventTrigger trigger = btn.gameObject.GetComponent<EventTrigger> ();
EventTrigger.Entry entry = new EventTrigger.Entry ();
// 鼠标点击事件
entry.eventID = EventTriggerType.PointerClick;
// 鼠标进入事件 entry.eventID = EventTriggerType.PointerEnter;
// 鼠标滑出事件 entry.eventID = EventTriggerType.PointerExit;
entry.callback = new EventTrigger.TriggerEvent ();
entry.callback.AddListener (OnClick);
// entry.callback.AddListener (OnMouseEnter);
trigger.triggers.Add (entry);
}
private void OnClick(BaseEventData pointData){
Debug.Log ("Button Clicked. EventTrigger..");
}
private void OnMouseEnter(BaseEventData pointData){
Debug.Log ("Button Enter. EventTrigger..");
}
}
4. 通过 MonoBehaviour 实现事件类接口来实现事件的监听 #
Step 1 : 通过 Hierarchy 面板创建 UI > Button
.
Step 2 : 创建一个 EventHandler.cs 脚本.
Step 3 : 将脚本绑定在 Button 对象上.
Step 4 : Done.
EventHandler.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class EventHandler : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IDragHandler {
public void OnPointerClick(PointerEventData eventData){
if(eventData.pointerId == -1){
Debug.Log ("Left Mouse Clicked.");
} else if(eventData.pointerId == -2){
Debug.Log ("Right Mouse Clicked.");
}
}
public void OnPointerEnter(PointerEventData eventData){
Debug.Log ("Pointer Enter..");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log ("Pointer Exit..");
}
public void OnPointerDown(PointerEventData eventData){
Debug.Log ("Pointer Down..");
}
public void OnDrag(PointerEventData eventData){
Debug.Log ("Dragged..");
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class EventHandler : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler, IPointerDownHandler, IDragHandler {
public void OnPointerClick(PointerEventData eventData){
if(eventData.pointerId == -1){
Debug.Log ("Left Mouse Clicked.");
} else if(eventData.pointerId == -2){
Debug.Log ("Right Mouse Clicked.");
}
}
public void OnPointerEnter(PointerEventData eventData){
Debug.Log ("Pointer Enter..");
}
public void OnPointerExit(PointerEventData eventData){
Debug.Log ("Pointer Exit..");
}
public void OnPointerDown(PointerEventData eventData){
Debug.Log ("Pointer Down..");
}
public void OnDrag(PointerEventData eventData){
Debug.Log ("Dragged..");
}
}
UGUI 如何判断 UI 元素被点击时是鼠标的哪个按键, 上面的代码中我们可以根据 eventData.pointerId 来监听是鼠标左键还是右键. 但是每个 UI 元素都创建一个 MonoBehaviour 来监听各个事件显然不好, 下面是通过利用 Delegate 和 Event 来做一个通用类 UIEventListener 来处理事件 (观察者模式).
UIEventListener.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class UIEventListener : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler {
// 定义事件代理
public delegate void UIEventProxy(GameObject gb);
// 鼠标点击事件
public event UIEventProxy OnClick;
// 鼠标进入事件
public event UIEventProxy OnMouseEnter;
// 鼠标滑出事件
public event UIEventProxy OnMouseExit;
public void OnPointerClick(PointerEventData eventData){
if (OnClick != null)
OnClick (this.gameObject);
}
public void OnPointerEnter(PointerEventData eventData){
if (OnMouseEnter != null)
OnMouseEnter (this.gameObject);
}
public void OnPointerExit(PointerEventData eventData){
if (OnMouseExit != null)
OnMouseExit (this.gameObject);
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class UIEventListener : MonoBehaviour, IPointerClickHandler, IPointerEnterHandler, IPointerExitHandler {
// 定义事件代理
public delegate void UIEventProxy(GameObject gb);
// 鼠标点击事件
public event UIEventProxy OnClick;
// 鼠标进入事件
public event UIEventProxy OnMouseEnter;
// 鼠标滑出事件
public event UIEventProxy OnMouseExit;
public void OnPointerClick(PointerEventData eventData){
if (OnClick != null)
OnClick (this.gameObject);
}
public void OnPointerEnter(PointerEventData eventData){
if (OnMouseEnter != null)
OnMouseEnter (this.gameObject);
}
public void OnPointerExit(PointerEventData eventData){
if (OnMouseExit != null)
OnMouseExit (this.gameObject);
}
}
TestEvent.cs
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestEvent : MonoBehaviour {
void Start () {
Button btn = this.GetComponent<Button> ();
UIEventListener btnListener = btn.gameObject.AddComponent<UIEventListener> ();
btnListener.OnClick += delegate(GameObject gb) {
Debug.Log(gb.name + " OnClick");
};
btnListener.OnMouseEnter += delegate(GameObject gb) {
Debug.Log(gb.name + " OnMouseEnter");
};
btnListener.OnMouseExit += delegate(GameObject gb) {
Debug.Log(gb.name + " OnMOuseExit");
};
}
}
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class TestEvent : MonoBehaviour {
void Start () {
Button btn = this.GetComponent<Button> ();
UIEventListener btnListener = btn.gameObject.AddComponent<UIEventListener> ();
btnListener.OnClick += delegate(GameObject gb) {
Debug.Log(gb.name + " OnClick");
};
btnListener.OnMouseEnter += delegate(GameObject gb) {
Debug.Log(gb.name + " OnMouseEnter");
};
btnListener.OnMouseExit += delegate(GameObject gb) {
Debug.Log(gb.name + " OnMOuseExit");
};
}
}
TestEvent 脚本绑定在 Button 上即可.
Project 结构
5. 通过 继承EventTrigger 实现按钮点击事件 #
EventTriggerListener.cs
1. using UnityEngine;
2. using UnityEngine.EventSystems;
3.
4. public class EventTriggerListener : EventTrigger
5. {
6. public delegate void VoidDelegate(GameObject go);
7. public VoidDelegate onClick;
8. public VoidDelegate onDown;
9. public VoidDelegate onEnter;
10. public VoidDelegate onExit;
11. public VoidDelegate onUp;
12. public VoidDelegate onSelect;
13. public VoidDelegate onUpdateSelect;
14. public VoidDelegate onDrag;
15. public VoidDelegate onDrop;
16. public VoidDelegate onDeselect;
17. public VoidDelegate onScroll;
18. public VoidDelegate onMove;
19. public VoidDelegate onInitializePotentialDrag;
20. public VoidDelegate onBeginDrag;
21. public VoidDelegate onEndDrag;
22. public VoidDelegate onSubmit;
23. public VoidDelegate onCancel;
24.
25. public override void OnPointerClick(PointerEventData eventData)
26. {
27. if (onClick != null) onClick(gameObject);
28. }
29. public override void OnPointerDown(PointerEventData eventData)
30. {
31. if (onDown != null) onDown(gameObject);
32. }
33. public override void OnPointerEnter(PointerEventData eventData)
34. {
35. if (onEnter != null) onEnter(gameObject);
36. }
37. public override void OnPointerExit(PointerEventData eventData)
38. {
39. if (onExit != null) onExit(gameObject);
40. }
41. public override void OnPointerUp(PointerEventData eventData)
42. {
43. if (onUp != null) onUp(gameObject);
44. }
45. public override void OnSelect(BaseEventData eventData)
46. {
47. if (onSelect != null) onSelect(gameObject);
48. }
49. public override void OnUpdateSelected(BaseEventData eventData)
50. {
51. if (onUpdateSelect != null) onUpdateSelect(gameObject);
52. }
53.
54. public override void OnDrag(PointerEventData eventData)
55. {
56. if (onDrag != null) onDrag(gameObject);
57. }
58.
59. public override void OnDrop(PointerEventData eventData)
60. {
61. if (onDrop != null) onDrop(gameObject);
62. }
63.
64. public override void OnDeselect(BaseEventData eventData)
65. {
66. if (onDeselect != null) onDeselect(gameObject);
67. }
68.
69. public override void OnScroll(PointerEventData eventData)
70. {
71. if (onScroll != null) onScroll(gameObject);
72. }
73.
74. public override void OnMove(AxisEventData eventData)
75. {
76. if (onMove != null) onMove(gameObject);
77. }
78.
79. public override void OnInitializePotentialDrag(PointerEventData eventData)
80. {
81. if (onInitializePotentialDrag != null) onInitializePotentialDrag(gameObject);
82. }
83.
84. public override void OnBeginDrag(PointerEventData eventData)
85. {
86. if (onBeginDrag != null) onBeginDrag(gameObject);
87. }
88.
89. public override void OnEndDrag(PointerEventData eventData)
90. {
91. if (onEndDrag != null) onEndDrag(gameObject);
92. }
93.
94. public override void OnSubmit(BaseEventData eventData)
95. {
96. if (onSubmit != null) onSubmit(gameObject);
97. }
98.
99. public override void OnCancel(BaseEventData eventData)
100. {
101. if (onCancel != null) onCancel(gameObject);
102. }
103.
104. /// <summary>
105. /// 获取或添加一个事件侦听器到指定的游戏对象。用法和NGUI一样
106. /// </summary>
107.
108. public static EventTriggerListener Get(GameObject go)
109. {
110. EventTriggerListener listener = go.GetComponent<EventTriggerListener>();
111. if (listener == null) listener = go.AddComponent<EventTriggerListener>();
112. return listener;
113. }
114.
115. }
这个方法的使用,大家一看就明白!通俗易懂。
下面就是使用了。
using UnityEngine;
using UnityEngine.UI;
public class testScript : MonoBehaviour
{
private Button testButton;
void Start()
{
testButton = transform.Find("Button").GetComponent<Button>();
//方法一:
testButton.onClick.AddListener(OnClickClllBack);
//方法二:
testButton.onClick.AddListener(delegate (){onClick(testButton.gameObject);});
//方法三:
EventTriggerListener.Get(testButton.gameObject).onClick = OnClickClaaBack;
}
//方法一回调:
private void OnClickClllBack()
{
Debug.Log(" AddListener : OnClick testButton....");
}
//方法二回调:
private void onClick(GameObject go)
{
Debug.Log("delegate : OnClick testButton....");
}
//方法三回调:
void OnClickClaaBack(GameObject go)
{
Debug.Log("EventTriggerListener: OnClick testButton....");
}
}
using UnityEngine;
using UnityEngine.UI;
public class testScript : MonoBehaviour
{
private Button testButton;
void Start()
{
testButton = transform.Find("Button").GetComponent<Button>();
//方法一:
testButton.onClick.AddListener(OnClickClllBack);
//方法二:
testButton.onClick.AddListener(delegate (){onClick(testButton.gameObject);});
//方法三:
EventTriggerListener.Get(testButton.gameObject).onClick = OnClickClaaBack;
}
//方法一回调:
private void OnClickClllBack()
{
Debug.Log(" AddListener : OnClick testButton....");
}
//方法二回调:
private void onClick(GameObject go)
{
Debug.Log("delegate : OnClick testButton....");
}
//方法三回调:
void OnClickClaaBack(GameObject go)
{
Debug.Log("EventTriggerListener: OnClick testButton....");
}
}
代码很简单,注释也写了。