[UGUI]你说UnityEngine.UI.Button是怎么通过拖动来增加OnClick的监听器的呢?

一.写在前面

按国际惯例,先来讲一讲怎么涉及到这里了.我希望一个UI模块在Awake场景加载之后就可以通过回调来响应服务器消息,但是因为这个模块在场景加载的时候并不会被激活,所以需要将事件的订阅提前到该模块被加载之前,这就让我想起来了UGUI的Button的onClick事件,既然如此那就让我们一起来发现真相把.

二.真相就在这里!

首先呢,UGUI是开源的,要看源码啊,就不得不推荐Resharper了,这个插件有一个Assembly Explorer的东西,可以看到dll中的内容.下面就是Button的源码.我们看到,Button的onClick是一个继承了UnityEvent的对象,而这个对象是被标记了"[Serializable]"的,表示这个对象可以被序列话,而根据UnityEvent,则我们的目的就达到了.

 1 // Decompiled with JetBrains decompiler
 2 // Type: UnityEngine.UI.Button
 3 // Assembly: UnityEngine.UI, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null
 4 // MVID: FFDB3AB2-A87C-4B43-B613-BCF0D7807E81
 5 // Assembly location: D:practiceTaiDouARPGLibraryUnityAssembliesUnityEngine.UI.dll
 6 
 7 using System;
 8 using System.Collections;
 9 using System.Diagnostics;
10 using UnityEngine;
11 using UnityEngine.Events;
12 using UnityEngine.EventSystems;
13 using UnityEngine.Serialization;
14 
15 namespace UnityEngine.UI
16 {
17   [AddComponentMenu("UI/Button", 30)]
18   public class Button : Selectable, IEventSystemHandler, IPointerClickHandler, ISubmitHandler
19   {
20     [SerializeField]
21     [FormerlySerializedAs("onClick")]
22     private Button.ButtonClickedEvent m_OnClick = new Button.ButtonClickedEvent();
23 
24     public Button.ButtonClickedEvent onClick
25     {
26       get
27       {
28         return this.m_OnClick;
29       }
30       set
31       {
32         this.m_OnClick = value;
33       }
34     }
35 
36     protected Button()
37     {
38     }
39 
40     private void Press()
41     {
42       if (!this.IsActive() || !this.IsInteractable())
43         return;
44       this.m_OnClick.Invoke();
45     }
46 
47     public virtual void OnPointerClick(PointerEventData eventData)
48     {
49       if (eventData.button != PointerEventData.InputButton.Left)
50         return;
51       this.Press();
52     }
53 
54     public virtual void OnSubmit(BaseEventData eventData)
55     {
56       this.Press();
57       if (!this.IsActive() || !this.IsInteractable())
58         return;
59       this.DoStateTransition(Selectable.SelectionState.Pressed, false);
60       this.StartCoroutine(this.OnFinishSubmit());
61     }
62 
63     [DebuggerHidden]
64     private IEnumerator OnFinishSubmit()
65     {
66       // ISSUE: object of a compiler-generated type is created
67       return (IEnumerator) new Button.u003COnFinishSubmitu003Ec__Iterator1()
68       {
69         u003Cu003Ef__this = this
70       };
71     }
72 
73     [Serializable]
74     public class ButtonClickedEvent : UnityEvent
75     {
76     }
77   }
78 }

 三.总结

其实这篇博客还没写完,为什么可以这样搞还没弄明白,等以后更新吧.

原文地址:https://www.cnblogs.com/WongSiuming/p/4988763.html