irpas技术客

【Unity知识点】通俗解释delegate,事件event,Action,Func和UnityAction,UnityEvent_真鬼123_unityact

未知 2825

委托delegate

委托可以理解为像类一样,声明的一种方法类型。

委托对象可以被赋值,注册和注销方法。委托对象必须被赋值才可使用。委托的使用类内和类外无差别。

public delegate void MyDelegate(int i); public MyDelegate myDelegate ; public void Start() { //委托delegate myDelegate = new MyDelegate(DoThing); myDelegate = DoThing;//等号赋值,更改委托内容 myDelegate += DoThing; myDelegate -= DoThing; myDelegate.Invoke(1); } public void DoThing(int i) { Debug.Log(i); }

通过Invoke()调用delegate;

事件event

事件是对委托的一个限定,事件对象不需要被赋值,也不能被赋值,可以注册和注销方法。也可以注册和注销委托。

不论声明为public还是private,事件对象在类外只能在+=号和-=号的左边,意味着在声明此事件的类外,无法使用,只能注册和注销方法。

public delegate void MyDelegate(int i); public MyDelegate myDelegate ; public event Mydelegate myEvent; public void Start() { //委托使用 myDelegate = new MyDelegate(DoThing); myDelegate= DoThing;//等号赋值,更改委托内容 myDelegate += DoThing; myDelegate -= DoThing; //事件使用 myEvent = DoThing; //在声明event的类中,可以为event赋值。 myEvent = myDelegate; myEvent += DoThing; myEvent -=DoThing; myEvent += myDelegate; myEvent -=MyDelegate; myEvent.Invoke(1); } public void DoThing(int i) { Debug.Log(i); }

通过Invoke()调用event;

Action

Action和Func可以理解为系统定义好的带泛型的delegate。Action是无返回值的。

Action<T>的泛型T,代表参数。

从使用上就可以看出来;

public Action<int> action; public void Start() { action = DoThing; action += DoThing; action -= DoThing; action.Invoke(1); } public void DoThing(int i) { Debug.Log(i); } Func

Action和Func可以理解为系统定义好的带泛型的delegate。Func是有返回值的。

Func<T,K>的前n-1个泛型代表参数, 最后一个泛型代表返回值类型。

public Func<int,int> action; public void Start() { action = DoThing; action += DoThing; action -= DoThing; int num = action.Invoke(1); } public int DoThing(int i) { Debug.Log(i); return i+1; }

如果向Func添加了多个不同方法,则返回值为最后添加的方法的返回值。

UnityAction

UnityAction是Unity对C#中Action的再次封装。是更适合在Unity中使用的一种泛型委托。

UnityAction对象可以用于Unity内的.AddListener()。

用法和Action一样。

public UnityAction<int> action; public void Start() { action = DoThing; action += DoThing; action -= DoThing; action.Invoke(1); } public void DoThing(int i) { Debug.Log(i); } UnityEvent

UnityEvent可以在面板中添加监听事件,也可以在代码中添加监听事件或UnityAction。而且这两个模式不会互通。

public UnityEvent<int> event0; public UnityEvent<int, string> event1;

他可以在Inspector面板显示,并且添加方法,就和Button按钮一样。 看起来是不是很眼熟?我们常用的UGUI中的Button点击事件,就继承自UnityEvent。

在Inspector中添加的事件,不受定义UnityEvent的参数限制,并且在代码中无法注销。(RemoveAllListeners无法注销在面板中设置的监听。)

Invoke的参数也只对代码中add的事件有效,在Inspector面板中添加的事件如果有参数,调用时使用面板设置的参数。

下面是UInityEvent在代码中的使用:

public UnityEvent<int> event0; public UnityEvent<int, string> event1; void Start() { event0.AddListener(DoThing_Int); event1.AddListener(DoThing_Int_Str); · //只会注销在代码中add的Listener,面板定义的监听还保存在event0中 event0.RemoveAllListeners(); event0.Invoke(0); event1.Invoke(0, "zzz"); } public void DoThing() { Debug.Log("DoThing"); } public void DoThing_Int(int i) { Debug.Log("DoThing_Int"+ i); } public void DoThing_Int_Str(int i, string str) { Debug.Log("DoThing_Int_Str" + i+ str); }


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #委托对象必须被赋值才可使用 #委托的使用类内和类外无差别