Unity中事件的3种实现方法

前言

假设有两个脚本A和脚本B,当A调用某一函数fn时,要发布事件,而监听A中事件的脚本B,要做出对应回应。对此有三种方法,
UnityEvent:有UI界面,不需要手动取消监听
event:物体被被摧毁时要手动取消监听或阻止函数继续运行
BroadcastMessage:方便于自身传递,但无法广播到被禁用的组件或被禁用物体上的

UnityEvent

UnityEvent持有对象的引用,当对象被销毁时就不会再调用对应函数了。类似于
if(obj != null) { obj.fn(…); }

//脚本A
using UnityEngine.Events;
public UnityEvent<...> attacked = new UnityEvent<...>();
public void fn() {
    
     attacked(...); }

在这里插入图片描述

event

//... 表示参数或参数类型,如Action,Action<GameObject>,Action<GameObject,int>等
//这里假设都挂有A组件,一般情况下需要判空
//脚本A
public event System.Action<...> attacked;
public void fn() {
    
     attacked(...); }

//脚本B
void Start(){
    
    
	GetComponent<A>().attacked += OnAttacked;
	otherObj.GetComponent<A>().attacked += OnAttacked;
}
void OnAttacked(...) {
    
    
	//do something
	print(gameObject.name);
}
void OnDestroyed(){
    
    
	//监听听自身的可忽略,除非有调用Object.Destroy(GetComponent(B)())
	//GetComponent<A>().attacked-= OnAttacked;
	  
	//监听其他物体的不可忽略,因为当B组件被销毁时,
	//其他物体上的A组件还会调用B中的函数,所以要取消
	otherObj.GetComponent<A>().attacked-= OnAttacked;
}

BroadcastMessage

BroadcastMessage向自身及子物体上所以“非禁用”脚本广播。
当物体被禁用(gameObject.SetActive(false))时,
其身上所以脚本和子物体上所以脚本都相当于“禁用”,就无法接受到广播。

public void BroadcastMessage(string methodName, 
object parameter = null,   
SendMessageOptions options = SendMessageOptions.RequireReceiver);

最后一个参数默认是有要求接收,如果没用接收就会报错。
如果不希望报错可以改为,SendMessageOptions.DontRequireReceiver

切换场景时static的注意事项

当切换场景时,没用调用过DontDestroyOnLoad()的GameObject及其脚本会被销毁,但是那些脚本上的static变量并不会消失。如:

//脚本A
static int v1;  //不变
static float v1;  //不变
static GameObject obj;  //obj被销毁,在使用前要判空  if(obj!=null) 或 if(obj)
static event System.Action action;  //保存的事件还在,可以用 action=null 来清空监听

猜你喜欢

转载自blog.csdn.net/weixin_46068322/article/details/125910897