您的位置:

UnityAction详解

一、什么是UnityAction

UnityAction是Unity3D中的一个委托(delegate),它是UnityEvent的基础。它可以将一组方法绑定到一个委托上,使这组方法可以一起被调用。UnityAction可以作为委托类型作为UnityEvent的参数被使用。

示例代码:

public delegate void UnityAction(); 

public class Example : MonoBehaviour { 
    public UnityAction myAction; 

    void Start(){ 
        if (myAction != null) 
            myAction(); 
    } 

    void Update(){ 
        if (Input.GetKeyDown(KeyCode.Space) && myAction != null) 
            myAction(); 
    } 
} 

二、UnityAction带参数

UnityAction也支持带参数的委托。创建带参数的UnityAction时,必须确保参数类型与绑定的方法的参数类型完全一致。对于多个参数的方法,可以使用System.Action<T1, T2, ..., Tn>,其中T1,T2,...,Tn是各个参数的类型。

示例代码:

public delegate void UnityActionWithArgs(int val1, float val2);

public class Example : MonoBehaviour {
	public static event UnityActionWithArgs onAction;

	private void Start() {
		onAction?.Invoke(1, 1.23f);
	}
}

三、UnityEvent与UnityAction调用方式

1.UnityEvent

UnityEvent对UnityAction进行了进一步的封装,提供了更多功能,例如Ajax、PlayOneShot和订阅者的持久存储。UnityEvent使用AddListener()方法添加回调函数,RemoveListener()方法移除回调函数,并使用Invoke()方法调用回调函数。 UnityEvent也可以使用generic参数来传递参数。

示例代码:

using UnityEngine;
using UnityEngine.Events;

public class Example : MonoBehaviour {
	public UnityEvent buttonEvent;

	void Update() {
		if (Input.GetKeyDown(KeyCode.Space)) {
			buttonEvent.Invoke();
		}
	}
}

2.UnityAction.Invoke()

UnityAction也可以与Invoke()一起使用,直接调用UnityAction中的方法。

示例代码:

public class Example : MonoBehaviour {
    public UnityAction myAction;

    void Start() {
        if (myAction != null) {
            myAction.Invoke();
        }
    }

    void Update() {
        if (Input.GetKeyDown(KeyCode.Space) && myAction != null) {
            myAction.Invoke();
        }
    }
}

四、UnityAction Invoke无参数和带参数的区别

UnityAction的Invoke()方法可以不带参数调用,也可以带参数调用。如果UnityAction没有参数,则Invoke()方法可以直接调用。如果UnityAction有参数,则Invoke()方法必须将与UnityAction相同的参数传递进去。

示例代码:

public class Example : MonoBehaviour {
    public UnityAction myActionWithoutArgs;
    public UnityAction<string> myActionWithArgs;

    void Start() {
        if (myActionWithoutArgs != null) {
            myActionWithoutArgs.Invoke();
        }
        if (myActionWithArgs != null) {
            myActionWithArgs.Invoke("Hello, world!");
        }
    }

    void Update() {
        // 同上...
    }
}

五、Unity委托详解

在Unity中,有多种类型的委托可供使用。除了UnityAction和UnityEvent之外,常用的委托类型还包括:System.Action、System.Func、以及自定义委托类型。

1.System.Action

System.Action与UnityAction非常相似,它们都是没有返回值的委托类型。Action定义了不同参数数量和类型的委托。例如,Action<T>表示带单个参数类型T的委托,Action<T1, T2>表示带有两个参数类型T1和T2的委托。

示例代码:

public class Example : MonoBehaviour {
	public System.Action myActionNoArgs;
	public System.Action<string> myActionWithArgs;

	void Start() {
		if (myActionNoArgs != null) {
			myActionNoArgs();
		}
		if (myActionWithArgs != null) {
			myActionWithArgs("Hello, world!");
		}
	}

	void Update() {
		// 同上...
	}
}

2.System.Func

System.Func是带返回值的委托类型,其返回类型是指定的类型。System.Func的定义方式与System.Action类似,它可以定义具有不同个数和类型的参数的委托。

示例代码:

public class Example : MonoBehaviour {
	public System.Func<int, float, bool> myFunc;

	void Start() {
		bool result = myFunc(1, 1.23f);

		if (result) {
			// do something
		}
	}

	void Update() {
		// 同上...
	}
}

3.自定义委托类型

自定义委托类型可以通过定义自己的类来实现。它可以定义各种类型的返回值和参数。

示例代码:

public delegate void CustomEvent(int id);

public class Example : MonoBehaviour {
	public CustomEvent customEvent;

	void Start() {
		if (customEvent != null) {
			customEvent(10);
		}
	}

	void Update() {
		// 同上...
	}
}