Three implementation methods of events in Unity

Three implementation methods of events in Unity

foreword

Suppose there are two scripts A and B, when A calls a certain function fn, an event needs to be published, and script B, which listens to the event in A, needs to make a corresponding response. There are three methods for this,
UnityEvent: There is a UI interface, no need to manually cancel the monitoring
Event: When the object is destroyed, manually cancel the monitoring or prevent the function from continuing to run
BroadcastMessage: It is convenient for self-transmission, but cannot be broadcast to disabled components or disable the object

UnityEvent

UnityEvent holds a reference to the object, and the corresponding function will not be called when the object is destroyed. Something like
if(obj != null) { obj.fn(…); }

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

insert image description here

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 broadcasts to all "non-disabled" scripts on itself and its children.
When an object is disabled (gameObject.SetActive(false)),
all scripts on its body and sub-objects are equivalent to "disabled" and cannot receive broadcasts.

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

The last parameter is required to be received by default, and an error will be reported if it is not used.
If you don't want to report an error, you can change it to SendMessageOptions.DontRequireReceiver

Notes on static when switching scenes

When switching scenes, GameObjects and their scripts that have not called DontDestroyOnLoad() will be destroyed, but the static variables on those scripts will not disappear. like:

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

Guess you like

Origin blog.csdn.net/weixin_46068322/article/details/125910897