在Unity中使用消息订阅
有什么不明白的地方,扫描右方二维码加我微信交流。
下面简单用报社订阅报纸的方式说一下什么是消息订阅。
报社是消息中心(MessageCenter),《人民日报》是消息体(Message),报纸上的信息是消息。人通过报社订阅《人民日报》,当《人民日报》的报纸到达报社,则给每个订阅人派发报纸。报纸到达每个订阅人手里,订阅人对报纸上的信息进行阅读处理。当订阅人出现意外状况(例如人间蒸发)不再需要报纸时,一定要取消订阅。如不取消,下次的报纸依然会派发过来,但是无人处理。现实中不会出什么问题,但在程序中就会出错。
下面上代码
using System.Collections.Generic;
//消息体
public class Message
{
public string Name //发送消息的名称
{
get;
}
public object Body //消息主体
{
get;
}
public Message(string name, object body)
{
Name = name;
Body = body;
}
}
//消息中心
public class MessageCenter
{
//委托
public delegate void MessageDelHandle(Message message);
//字典<key,委托>
private readonly Dictionary<string, MessageDelHandle> _messageMap = new Dictionary<string, MessageDelHandle>();
//单例
private static MessageCenter _instance;
public static MessageCenter GetInstance()
{
return _instance ?? (_instance = new MessageCenter());
}
//添加监听
public void AddListener(string messageName, MessageDelHandle handle = null)
{
if (handle == null) return;
if (!_messageMap.ContainsKey(messageName))
{
_messageMap.Add(messageName, handle);
}
else
{
_messageMap[messageName] -= handle;//避免重复添加
_messageMap[messageName] += handle;
}
}
//移除监听
public void RemoveListener(string messageName, MessageDelHandle handle = null)
{
if (handle == null) return;
if (_messageMap.ContainsKey(messageName))
{
_messageMap[messageName] -= handle;
}
if (_messageMap[messageName] == null)
{
_messageMap.Remove(messageName);
}
}
//发送消息
public void EmitMessage(string messageName, object body = null)
{
if (!_messageMap.ContainsKey(messageName)) return;
_messageMap.TryGetValue(messageName, out var handle);
if (handle != null)
{
handle(new Message(messageName, body));
}
}
}
使用方法:
using UnityEngine;
public class SceneInit : MonoBehaviour
{
// Start is called before the first frame update
void Start()
{
//订阅消息
MessageCenter.GetInstance().AddListener("test", Test1);
MessageCenter.GetInstance().AddListener("test", Test2);
}
private void OnDestroy()
{
//取消订阅
MessageCenter.GetInstance().RemoveListener("test", Test1);
MessageCenter.GetInstance().RemoveListener("test", Test2);
}
private static void Test1(Message message)
{
Debug.Log(1);
}
private static void Test2(Message message)
{
Debug.Log(message.Name);
Debug.Log(message.Body);
// var a = (int[]) message.Body;
// var a = (Hashtable) message.Body;
}
public void OnBtnClk(string btnType)
{
switch (btnType)
{
case "send":
//消息的body可以使用任何数据类型,在使用时注意对数据进行类型转换
MessageCenter.GetInstance().EmitMessage("test", "123123123");
// MessageCenter.GetInstance().EmitMessage("test", new Hashtable(){{"abc", 123}});
// MessageCenter.GetInstance().EmitMessage("test", new int[]{1, 2, 3});
break;
}
}
}