一、简介
Unity提供的消息推送机制可以非常方便我们的脚本开发,它实现的是一种 伪监听者模式,利用的是反射机制。
一共有3种实现方式:
//1.发送给自身的所有脚本 (只发给自身所有脚本)
SendMessage("方法名称");
//2.发送给自身的所有脚本以及自身父物体,父物体的父物体等身上所有脚本 (发给自己和父物体,及父物体的父物体 往上调用)
SendMessageUpwards("方法名称");
//3.还有发给自己和子物体,及子物体的子物体,往下调用。
BroadcastMessage("方法名称");
二、准备工作
新建SendMessageTest 类,这个类负责发送消息
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SendMessageTest : MonoBehaviour
{
void Start()
{
// 发送给自身的所有脚本
SendMessage("GetMessage");
// 发送给自身的所有脚本以及自身父物体,父物体的父物体等身上所有脚本
//SendMessageUpwards("GetMessage");
// 发送给自身的所有脚本以及自身子物体,子物体的子物体等身上所有脚本
//BroadcastMessage("GetMessage");
}
private void GetMessage()
{
Debug.Log("SendMessageTest脚本,自己本身,方法类型private");
}
}
我们在新建三个类,分别挂载在父物体,自己本身,子物体上
GetMessageSelf 类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//自己本身
public class GetMessageSelf : MonoBehaviour
{
private void GetMessage()
{
Debug.Log("GetMessageSelf脚本,自己本身,方法类型private");
}
}
GetMessageChild 类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class GetMessageChild : MonoBehaviour
{
public void GetMessage()
{
Debug.Log("GetMessageChild脚本,子物体,方法类型public");
}
}
GetMessageParent 类
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
//父物体
public class GetMessageParent : MonoBehaviour
{
protected void GetMessage()
{
Debug.Log("GetMessageParent脚本,父物体,方法类型protected");
}
}
将这三个类挂载到对应物体上
self物体挂载
Parent物体挂载
Child物体挂载
三、具体实现
1.执行SendMessageTest 的SendMessage()方法效果
SendMessageTest类和GetMessageSelf类中的GetMessage()被执行
2.执行SendMessageTest 的SendMessageUpwards()方法效果
SendMessageTest类、GetMessageSelf类和GetMessageParent中的GetMessage()被执行
3.执行SendMessageTest 的BroadcastMessage()方法效果
SendMessageTest类、GetMessageSelf类和GetMessageChild中的GetMessage()被执行
四、扩展
1.如果方法中需要传值怎么办?
我们新建一个物体挂载脚本
public class SendMessageTest : MonoBehaviour
{
void Start()
{
// 发送给自身的所有脚本
SendMessage("GetMessage","AAAA");
}
private void GetMessage(string a)
{
Debug.Log("收到的消息"+a);
}
}
运行效果:
2.如果SendMessage()没有找到方法,想让他打印未找到的错误提示?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SendMessageTest : MonoBehaviour
{
void Start()
{
SendMessage("GetMessageAA", SendMessageOptions.RequireReceiver);
}
private void GetMessage()
{
Debug.Log("收到的消息");
}
}
SendMessageOptions枚举,SendMessage()方法默认SendMessageOptions是 DontRequireReceiver
public enum SendMessageOptions
{
//提示错误信息
RequireReceiver = 0,
//不提示错误信息
DontRequireReceiver = 1
}
3. 如果方法需要多种参数如何传值?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class SendMessageTest : MonoBehaviour
{
int a = 1;
string b = "BBBB";
bool c = false;
object[] _obj;//使用object[] 数组存储方法所需要的值
void Start()
{
_obj = new object[] { a,b,c};
// 发送给自身的所有脚本
SendMessage("GetMessage", _obj);
}
private void GetMessage(object[] obj)
{
Debug.Log("参数1: "+ obj[0]);
Debug.Log("参数2: "+ obj[1]);
Debug.Log("参数3: "+ obj[2]);
}
}
五、总结
SendMessage发送方式一共有三种:
1. SendMessage("方法名"); //发送给自身的所有脚本
2.SendMessageUpwards("方法名"); //发送给自身的所有脚本以及自身父物体,父物体的父物体等身上所有脚本
3.BroadcastMessage("方法名"); //发送给自身的所有脚本以及自身子物体,子物体的子物体等身上所有脚本
两种SendMessageOptions方式
1.SendMessage("方法名", SendMessageOptions.RequireReceiver);//未找到方法,报错
2.SendMessageUpwards("方法名", " SendMessageOptions.DontRequireReceiver); //默认模式 未找到方法,不报错
任何访问修饰符的方法都会被调用(上方举例中测试了 public private protected)