Unity3d C# 广播消息 事件代理与委托

来源:互联网 发布:gala乐队知乎 编辑:程序博客网 时间:2024/05/17 07:09

广播与消息

函数原型:

public void ReceiveBroadcastMessage (string methodName, object value);

public void SendMessage (string methodName, object value)

public void SendMessageUpwards (string methodName, object value)

可以传递参数类型object(类如Gamobject string int ........)

消息会广播到所有脚本,但是工程中至少要有序一个相应接收消息的函数,否则触发消息时会报错。



// 向子类和自己发送消息

gameObject.BroadcastMessage ("ReceiveBroadcastMessage", "A0-----BroadcastMessage()");

//向自己发送消息
 gameObject.SendMessage ("ReceiveSendMessage", "A0-----SendMessage()");

//向父类和自己发送消息
 gameObject.SendMessageUpwards ("ReceiveSendMessage", "A0-----SendMessageUpwards()");

 

void ReceiveBroadcastMessage(str : String){
 Debug.Log("A0----ReceiveBroadcastMessage" +str);
}
void ReceiveSendMessage(str : String){
 Debug.Log("A0----ReceiveSendMessage" +str);
}
void  ReceiveSendMessageUpwards (str : String){
 Debug.Log("A0----ReceiveSendMessageUpwards"  +str);
}

ReceiveBroadcastMessage、ReceiveSendMessageReceiveSendMessage为自定义函数。


代理与委托

public class Message:MonoBehaviour{

public delegate void EventHandler(int num)

public static event EventHandler OnSendMessage;

void OnClick()
{
if(OnSendMessage!=null)
OnsendMessage(2);
}

}
接收:
Message.OnSendMessage+=ReceiveMessage;

public void ReceiveMessage(int num)
{
Debug.Log("ReceiveMessage="+num);
}

Message.cs中要判断一下委托是否为空。如果为空的话是会有错误的。比如

Message.Receive += ReceiveMessage;

这段代码的意思就是为委托事件赋值,让本类的DoOnethine(string str)方法接受委托传递回来的事件,这里起到一个回调的作用。

对比:
一、速度
大概快个10倍的样子,频繁调用和响应其他方法的时候,我们得使用Delegate的委托事件取代SendMessage。


二、在多线程Thread下使用Delegate要注意

1、我们应该知道Monobehaviour提供的一些快捷的API去调用,例如:FindObjectOfType,GameObject.Find,SendMessage,StartCoroutine……等等。

如果在其他线程去调用这些的话,那么我们肯定会遇到错误的提示,提示这些方法只能在Mainthread中调用,请把它们的构造方法放到Awake或者Start。如果是Delegate在多线程中响应了相关方法,要去启动一个Coroutine,那么绝对会报错的。

为什么呢?

1.1、记住Unity3D是有一个单线程程序,就是它有一个主线程处理各种UnityEngine中的MonoBehaviour 便捷的查找方式都只能在默认的主线程中去调用。(我的项目就涉及到多线程处理数据的问题,就遇到这种莫名其妙的错误,因为Delegate委托代理者和方法是分开的,写主线程的方法很容易会带有MonoBehaviour里U3D自带的API,目前我发现要在其他线程启动一个协程确实不太好使)


2、在Thread中的Delegate响应去使某个对象,这个对象又是在MonoBehaviour中Awake或者Start初始化的话,很容易造成空引用的错误。






0 0
原创粉丝点击