一.写在前面
按国际惯例,先来讲一讲怎么涉及到这里了.我希望一个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 }
三.总结
其实这篇博客还没写完,为什么可以这样搞还没弄明白,等以后更新吧.