版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/LinZhonglong/article/details/81131097
PS:最近看到有很多地方用到UnityAction和UnityEvent的地方,自己也刚刚学习,总结一下
Action 与event
Action也是基于委托,并且无返回值。可带参数Action<T1,T2,T3,T4>。通常大家可以用在订阅事件和发出消息结合。这点和delegate配合event很相似。它们在程序运行时[动态绑定]
class MyClass:MonoBehavior
{
public delegate void MyDelegate();
public event MyDelegate eventHandler;
//对所有订阅过该事件的订阅者发消息
public void SendMessage()
{
if(eventHandler!=null)
{
eventHandler();
}
}
}
class MyTest:MonoBehavior
{
public system.Action callBack;
void Start()
{
callBack=MyFunction;
}
void MyFunction()
{
//...
}
//此过程等于调用MyFunction函数。可以是其他类的函数
public void SendMessage()
{
this.callBack();
}
}
从上面可以看出Action等于传递了一个函数,不同于普遍使用的传数据类型,传类
UnityAction与UnityEvent
既然event可以方便的传递消息,那Unity开发者自然也有自己的UnityEvent。比如简单Button使用的时候,我们把对象拖入Runtime中,然后选择我们所需要的调用函数。其实使用的就是Runtime里的UnityEvent,这里的拖入完成的就是注册
在我们的类中声明如下,并作序列化
可以在Inspector面板看到
是不是和Button等可交互对象上似曾相识呢?
说到这里那UnityAction呢?其实它和Action一样,都需要绑定对应的函数。UnityEvent里也需要注册UnityAcrtion.这样当我们调用UnityEvent的Invoke方法后,它会对所有注册过的UnityAction发出回调。例如
using UnityEngine;
using System.Collections;
using UnityEngine.Events;
public class UnityActionAndEvent : MonoBehaviour {
public UnityAction action;
public UnityEvent myEvent = new UnityEvent();
void Start()
{
action = new UnityAction(MyFunction);
action+=MyFunction2;
myEvent.AddListener(action);
//AddListener的时候也可采用匿名委托,省去UnityAction
myEvent.AddListener(()=>
{
//此处等于一个函数体,要处理的逻辑
}
);
}
void Update()
{
if(Input.GetKeyDown(KeyCode.Space))
{
myEvent.Invoke();
}
}
public void MyFunction()
{
print ("MyFunction");
}
public void MyFunction2()
{
print ("MyFunction2");
}
}
到这里基本使用应该没问题了,那么带参的有必要提一下。
UnityEvent<T0> 是抽象类,需要继承。
public class MyEvent:UnityEvent<int>{}
public class UnityActionWithParameter : MonoBehaviour {
public MyEvent myEvent = new MyEvent();
public UnityAction<int> action;
void Start () {
action= new UnityAction<int>(MyFunction);
action += MyFunction2;
myEvent.AddListener(action);
}
void Update () {
if(Input.GetKeyDown(KeyCode.A))
{
myEvent.Invoke(10);
}
}
public void MyFunction(int i)
{
print (i);
}
public void MyFunction2(int i)
{
print(i*2);
}
}
如果说使用Action可以完成简单回调一对一使用的话,那么通过UnityEvent则可以完成对所有注册过的UnityAction实现一对多通知。
PS:欢迎一起交流学习,指正