网络知识 娱乐 【Unity知识点】通俗解释delegate,事件event,Action,Func和UnityAction,UnityEvent

【Unity知识点】通俗解释delegate,事件event,Action,Func和UnityAction,UnityEvent

委托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,代表参数。

从使用上就可以看出来;

public Action 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的前n-1个泛型代表参数, 最后一个泛型代表返回值类型。

public Func 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 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 event0;
 public UnityEvent event1;

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

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

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

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

 public UnityEvent event0;
 public UnityEvent 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);
    }