项目里需要一个简易的消息派发机制,用途更偏向"订阅"——各个对象向中心登记自己关心的消息,中心在合适的时机把消息广播给所有订阅者。下面给出一个基于 Unity 的最小实现。

设计思路

整个机制由两部分组成:一个是 Recver,用来描述一个订阅者,记录它关心的消息名、对应的 GameObject 以及回调委托;另一个是 NotifyCenter,它挂在场景中的某个对象上,以单例的方式持有所有订阅者,并提供注册、注销和广播接口。

对外接口

  • addRecver:注册一个订阅者,指定消息名和回调。
  • removeRecver:按消息名 + GameObject 注销订阅。
  • sendMessage:按消息名广播,所有匹配的订阅者都会被回调。

完整代码

using UnityEngine;
                using System.Collections;
                using System.Collections.Generic;
                
                
                public delegate void HandlerNotifyCenter(System.Object arg);
                
                
                
                [System.Serializable]
                class Recver
                {
                
                    public string name;
                    public GameObject recver;
                
                    public HandlerNotifyCenter handler;
                    public Recver()
                    {
                
                
                    }
                
                    public void InVoke(System.Object arg)
                    {
                        handler(arg);
                    }
                }
                
                
                public class NotifyCenter : MonoBehaviour
                {
                    static public NotifyCenter ins;
                
                    List<Recver> recvers = new List<Recver>();
                
                
                
                    void Awake()
                    {
                        ins = this;
                    }
                    // Use this for initialization
                    void Start()
                    {
                
                    }
                
                    // Update is called once per frame
                    void Update()
                    {
                
                    }
                
                
                
                    public void addRecver(GameObject recver, string name, HandlerNotifyCenter handler)
                    {
                        // gameObject.SendMessage(msg);
                
                        Recver x = new Recver();
                        x.name = name;
                        x.handler = handler;
                        x.recver = recver;
                        recvers.Add(x);
                    }
                
                
                    public void removeRecver(GameObject recver, string name)
                    {
                        foreach (Recver obj in recvers)
                        {
                            if (name == obj.name && recver == obj.recver)
                            {
                                recvers.Remove(obj);
                            }
                        }
                
                
                
                    }
                
                    public void sendMessage(string msg, System.Object arg)
                    {
                        foreach (Recver obj in recvers)
                        {
                            if (msg == obj.name)
                            {
                                obj.InVoke(arg);
                            }
                        }
                    }
                
                }