在项目中,脚本相互引用会造成耦合性的增加,而使用消息订阅分发,可以解耦合。
using UnityEngine;
using System.Collections.Generic;
using System;
/// <summary>
/// 委托事件类型Typ
/// </summary>
public enum MessageMediatType
{
GetDiamond, // 获得钻石
GetMoney, // 获得钱币
LevelUp, // 升级
}
public class MessageMediator
{
//泛型委托
public delegate void Act();
public delegate void Act<T>(T t);
public delegate void Act<T1, T2>(T1 t1, T2 t2);
public delegate void Act<T1, T2, T3>(T1 t1, T2 t2, T3 t3);
public delegate void Act<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4);
//public delegate void Act<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5);
/// <summary>
/// 存取订阅事件字典 K为类型 value为相对应委托
/// </summary>
static Dictionary<MessageMediatType, Delegate> messageTable = new Dictionary<MessageMediatType, Delegate>();
#region 注册监听
/// <summary>
/// 注册监听事件
/// </summary>
/// <param name="type">事件类型</param>
/// <param name="act">事件处理方法</param>
public static void AddListener(MessageMediatType type, Act act)
{
if (!messageTable.ContainsKey(type)) //如果要增加监听事件的类型不存在 就把新的类型和委托方法加载到管理订阅事件字典中
{
messageTable.Add(type, null);
}
Delegate d = messageTable[type];
if (d != null && d.GetType() != act.GetType()) //如果在要加载监听事件已存在此类型 判断这个类型的处理方法是否为空 是否和自己要加载的处理方法类型相同
{
Debug.LogError(string.Format("尝试为事件类型 {0} 添加不一致的签名的侦听器. 当前的监听器有type {1} 而监听器被添加了type {2}", type, d.GetType().Name, act.GetType().Name));
//Debug.LogError(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", type, d.GetType().Name, act.GetType().Name));
}
else
{
messageTable[type] = (Act)messageTable[type] + act;
}
}
/// <summary>
/// 泛型委托注册监听
/// </summary>
/// <typeparam name="T">委托类型</typeparam>
/// <param name="type"></param>
/// <param name="act"></param>
public static void AddListener<T>(MessageMediatType type, Act<T> act)
{
if (!messageTable.ContainsKey(type))
{
messageTable.Add(type, null);
}
Delegate d = messageTable[type];
if (d != null && d.GetType() != act.GetType())
{
Debug.LogError(string.Format("尝试为事件类型 {0} 添加不一致的签名的侦听器. 当前的监听器有type {1} 而监听器被添加了type {2}", type, d.GetType().Name, act.GetType().Name));
// Debug.LogError(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", type, d.GetType().Name, act.GetType().Name));
}
else
{
messageTable[type] = (Act<T>)messageTable[type] + act;
}
}
public static void AddListener<T1, T2>(MessageMediatType type, Act<T1, T2> act)
{
if (!messageTable.ContainsKey(type))
{
messageTable.Add(type, null);
}
Delegate d = messageTable[type];
if (d != null && d.GetType() != act.GetType())
{
Debug.LogError(string.Format("尝试为事件类型 {0} 添加不一致的签名的侦听器. 当前的监听器有type {1} 而监听器被添加了type {2}", type, d.GetType().Name, act.GetType().Name));
//Debug.LogError(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", type, d.GetType().Name, act.GetType().Name));
}
else
{
messageTable[type] = (Act<T1, T2>)messageTable[type] + act;
}
}
public static void AddListener<T1, T2, T3>(MessageMediatType type, Act<T1, T2, T3> act)
{
if (!messageTable.ContainsKey(type))
{
messageTable.Add(type, null);
}
Delegate d = messageTable[type];
if (d != null && d.GetType() != act.GetType())
{
Debug.LogError(string.Format("尝试为事件类型 {0} 添加不一致的签名的侦听器. 当前的监听器有type {1} 而监听器被添加了type {2}", type, d.GetType().Name, act.GetType().Name));
//Debug.LogError(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", type, d.GetType().Name, act.GetType().Name));
}
else
{
messageTable[type] = (Act<T1, T2, T3>)messageTable[type] + act;
}
}
public static void AddListener<T1, T2, T3, T4>(MessageMediatType type, Act<T1, T2, T3, T4> act)
{
if (!messageTable.ContainsKey(type))
{
messageTable.Add(type, null);
}
Delegate d = messageTable[type];
if (d != null && d.GetType() != act.GetType())
{
Debug.LogError(string.Format("尝试为事件类型 {0} 添加不一致的签名的侦听器. 当前的监听器有type {1} 而监听器被添加了type {2}", type, d.GetType().Name, act.GetType().Name));
//Debug.LogError(string.Format("Attempting to add listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being added has type {2}", type, d.GetType().Name, act.GetType().Name));
}
else
{
messageTable[type] = (Act<T1, T2, T3, T4>)messageTable[type] + act;
}
}
#endregion
#region 移除监听
/// <summary>
/// 移除监听委托事件
/// </summary>
/// <param name="type">委托事件类型</param>
/// <param name="listenerBeingRemoved">委托事件处理方法</param>
public static void RemoveListener(MessageMediatType type, Act listenerBeingRemoved)
{
if (messageTable.ContainsKey(type)) //查询储存委托事件的字典中是否存在相对应的类型 如果存在
{
Delegate d = messageTable[type];
if (d == null) //判断此类型的委托事件处理方法是否为空
{
Debug.LogError(string.Format("试图删除事件类型为\"{0}\" 的监听器,但是当前监听器是null.", type));
//Debug.LogError(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", type));
}
else if (d.GetType() != listenerBeingRemoved.GetType()) //如果此类型只的委托方法 和自己要移除的方法类型不同
{
Debug.LogError(string.Format("尝试用不一致的签名来删除事件类型 {0} 的监听器. 当前的监听器有类型 {1} 监听器被删除的类型为 {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
//Debug.LogError(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
else
{
messageTable[type] = (Act)messageTable[type] - listenerBeingRemoved; //吧此类型的委托处理发放从委托只移除
if (d == null) //如果移除后委托事件处理方法为空 就把此类型从存取订阅事件字典移除
{
messageTable.Remove(type);
}
}
}
else
{
Debug.LogError(string.Format("试图将侦听器删除为 \"{0}\" 但是Messenger并不知道这个事件类型.", type));
//Debug.LogError(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", type));
}
}
public static void RemoveListener<T>(MessageMediatType type, Act<T> listenerBeingRemoved)
{
if (messageTable.ContainsKey(type))
{
Delegate d = messageTable[type];
if (d == null)
{
Debug.LogError(string.Format("试图删除事件类型为\"{0}\" 的监听器,但是当前监听器是null.", type));
// Debug.LogError(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", type));
}
else if (d.GetType() != listenerBeingRemoved.GetType())
{
Debug.LogError(string.Format("尝试用不一致的签名来删除事件类型 {0} 的监听器. 当前的监听器有类型 {1} 监听器被删除的类型为 {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
//Debug.LogError(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
else
{
messageTable[type] = (Act<T>)messageTable[type] - listenerBeingRemoved;
if (d == null)
{
messageTable.Remove(type);
}
}
}
else
{
Debug.LogError(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", type));
}
}
public static void RemoveListener<T1, T2>(MessageMediatType type, Act<T1, T2> listenerBeingRemoved)
{
if (messageTable.ContainsKey(type))
{
Delegate d = messageTable[type];
if (d == null)
{
Debug.LogError(string.Format("试图删除事件类型为\"{0}\" 的监听器,但是当前监听器是null.", type));
//Debug.LogError(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", type));
}
else if (d.GetType() != listenerBeingRemoved.GetType())
{
Debug.LogError(string.Format("尝试用不一致的签名来删除事件类型 {0} 的监听器. 当前的监听器有类型 {1} 监听器被删除的类型为 {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
//Debug.LogError(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
else
{
messageTable[type] = (Act<T1, T2>)messageTable[type] - listenerBeingRemoved;
if (d == null)
{
messageTable.Remove(type);
}
}
}
else
{
Debug.LogError(string.Format("试图将侦听器删除为 \"{0}\" 但是Messenger并不知道这个事件类型.", type));
//Debug.LogError(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", type));
}
}
public static void RemoveListener<T1, T2, T3>(MessageMediatType type, Act<T1, T2, T3> listenerBeingRemoved)
{
if (messageTable.ContainsKey(type))
{
Delegate d = messageTable[type];
if (d == null)
{
Debug.LogError(string.Format("试图删除事件类型为\"{0}\" 的监听器,但是当前监听器是null.", type));
//Debug.LogError(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", type));
}
else if (d.GetType() != listenerBeingRemoved.GetType())
{
Debug.LogError(string.Format("尝试用不一致的签名来删除事件类型 {0} 的监听器. 当前的监听器有类型 {1} 监听器被删除的类型为 {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
//Debug.LogError(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
else
{
messageTable[type] = (Act<T1, T2, T3>)messageTable[type] - listenerBeingRemoved;
if (d == null)
{
messageTable.Remove(type);
}
}
}
else
{
Debug.LogError(string.Format("试图将侦听器删除为 \"{0}\" 但是Messenger并不知道这个事件类型.", type));
// Debug.LogError(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", type));
}
}
public static void RemoveListener<T1, T2, T3, T4>(MessageMediatType type, Act<T1, T2, T3, T4> listenerBeingRemoved)
{
if (messageTable.ContainsKey(type))
{
Delegate d = messageTable[type];
if (d == null)
{
Debug.LogError(string.Format("试图删除事件类型为\"{0}\" 的监听器,但是当前监听器是null.", type));
//Debug.LogError(string.Format("Attempting to remove listener with for event type \"{0}\" but current listener is null.", type));
}
else if (d.GetType() != listenerBeingRemoved.GetType())
{
Debug.LogError(string.Format("尝试用不一致的签名来删除事件类型 {0} 的监听器. 当前的监听器有类型 {1} 监听器被删除的类型为 {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
//Debug.LogError(string.Format("Attempting to remove listener with inconsistent signature for event type {0}. Current listeners have type {1} and listener being removed has type {2}", type, d.GetType().Name, listenerBeingRemoved.GetType().Name));
}
else
{
messageTable[type] = (Act<T1, T2, T3, T4>)messageTable[type] - listenerBeingRemoved;
if (d == null)
{
messageTable.Remove(type);
}
}
}
else
{
Debug.LogError(string.Format("试图将侦听器删除为 \"{0}\" 但是Messenger并不知道这个事件类型.", type));
//Debug.LogError(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", type));
}
}
/// <summary>
/// 清空指定类型的委托事件处理方法
/// </summary>
/// <param name="type">要删除的类型</param>
public static void RemoveAllListener(MessageMediatType type)
{
if (messageTable.ContainsKey(type))
{
messageTable[type] = null;
messageTable.Remove(type);
}
else
{
Debug.LogError(string.Format("试图将侦听器删除为 \"{0}\" 但是Messenger并不知道这个事件类型.", type));
// Debug.LogError(string.Format("Attempting to remove listener for type \"{0}\" but Messenger doesn't know about this event type.", type));
}
}
#endregion
#region 分配消息
/// <summary>
/// 当收到消息后分配消息
/// </summary>
/// <param name="type">消息的类型</param>
public static void Dispatch(MessageMediatType type)
{
Delegate d; //声明一个用来储存 处理此类型委托
if (messageTable.TryGetValue(type, out d))
{
Act callback = d as Act;
if (callback != null)
{
callback(); //如果此类型的消息处理事件方法不为空执行方法
}
else
{
Debug.LogError(string.Format("没有这样的事件类型为 {0}", type));
//Debug.LogError(string.Format("no such event type {0}", type));
}
}
}
public static void Dispatch<T>(MessageMediatType type, T param1)
{
Delegate d;
if (messageTable.TryGetValue(type, out d))
{
Act<T> callback = d as Act<T>;
if (callback != null)
{
callback(param1);
}
else
{
Debug.LogError(string.Format("没有这样的事件类型为 {0}", type));
//Debug.LogError(string.Format("no such event type {0}", type));
}
}
}
public static void Dispatch<T1, T2>(MessageMediatType type, T1 param1, T2 param2)
{
Delegate d;
if (messageTable.TryGetValue(type, out d))
{
Act<T1, T2> callback = d as Act<T1, T2>;
if (callback != null)
{
callback(param1, param2);
}
else
{
Debug.LogError(string.Format("没有这样的事件类型为 {0}", type));
// Debug.LogError(string.Format("no such event type {0}", type));
}
}
}
public static void Dispatch<T1, T2, T3>(MessageMediatType type, T1 param1, T2 param2, T3 param3)
{
Delegate d;
if (messageTable.TryGetValue(type, out d))
{
Act<T1, T2, T3> callback = d as Act<T1, T2, T3>;
if (callback != null)
{
callback(param1, param2, param3);
}
else
{
Debug.LogError(string.Format("没有这样的事件类型为 {0}", type));
//Debug.LogError(string.Format("no such event type {0}", type));
}
}
}
public static void Dispatch<T1, T2, T3, T4>(MessageMediatType type, T1 param1, T2 param2, T3 param3, T4 param4)
{
Delegate d;
if (messageTable.TryGetValue(type, out d))
{
Act<T1, T2, T3, T4> callback = d as Act<T1, T2, T3, T4>;
if (callback != null)
{
callback(param1, param2, param3, param4);
}
else
{
Debug.LogError(string.Format("没有这样的事件类型为 {0}", type));
//Debug.LogError(string.Format("no such event type {0}", type));
}
}
}
#endregion
}
测试代码:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class Tset : MonoBehaviour {
void Start()
{
//注册监听获得金币事件 参数一为事件类型 参数二为事件回调函数
MessageMediator.AddListener<int>(MessageMediatType.GetMoney, MoneyCallBack);
//事件触发 执行回调函数
MessageMediator.Dispatch(MessageMediatType.GetMoney, 100);
//移除所有监听法法
MessageMediator.RemoveListener<int>(MessageMediatType.GetMoney, MoneyCallBack);
MessageMediator.AddListener<int, float>(MessageMediatType.LevelUp, LevelUpCallBack1);
MessageMediator.AddListener<int, float>(MessageMediatType.LevelUp, LevelUpCallBack2);
MessageMediator.Dispatch(MessageMediatType.LevelUp, 2, 392f);
MessageMediator.RemoveListener<int, float>(MessageMediatType.LevelUp, LevelUpCallBack1);
MessageMediator.Dispatch<int, float>(MessageMediatType.LevelUp, 3, 256f);
}
/// <summary>
/// 获得金币的方法
/// </summary>
/// <param name="coin"></param>
private void MoneyCallBack(int coin)
{
Debug.Log("获得金币回调函数 " + coin);
}
/// <summary>
/// 增加等级增加经验的方法1
/// </summary>
/// <param name="level"></param>
/// <param name="exp"></param>
private void LevelUpCallBack1(int level, float exp)
{
Debug.Log("增加等级,增加经验,回调函数 1 。" + level + " " + exp);
}
/// <summary>
/// 增加等级增加经验的方法2
/// </summary>
/// <param name="level"></param>
/// <param name="exp"></param>
private void LevelUpCallBack2(int level, float exp)
{
Debug.Log("增加等级,增加经验,回调函数 2 " + level + " " + exp);
}
}
