在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; } } }