我们先看事件管理器的代码
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
/// <summary>
/// 委托重载
/// </summary>
public delegate void CallBack();
public delegate void CallBack<T>(T arg);
public delegate void CallBack<T, X>(T arg1, X arg2);
public delegate void CallBack<T, X, Y>(T arg1, X arg2, Y arg3);
public delegate void CallBack<T, X, Y, Z>(T arg1, X arg2, Y arg3, Z arg4);
public delegate void CallBack<T, X, Y, Z, W>(T arg1, X arg2, Y arg3, Z arg4, W arg5);
/// <summary>
/// 事件类型的枚举
/// </summary>
public enum EventType
{
ShowText,
}
public class EventCenter
{
/// <summary>
/// 事件系统管理器
/// </summary>
/// 方法是静态的方便调用
//静态字典
private static Dictionary<EventType, Delegate> m_EventTable = new Dictionary<EventType, Delegate>();
//判断是否存在某个键的抛出异常方法
private static void OnListenerAdding(EventType eventType, Delegate callBack)
{
if (!m_EventTable.ContainsKey(eventType))
{
m_EventTable.Add(eventType, null);
}
Delegate d = m_EventTable[eventType];
if (d != null && d.GetType() != callBack.GetType())
{
throw new Exception(string.Format("尝试为事件{0}添加不同类型的委托,当前事件所对应的委托是{1},要添加的委托类型为{2}", eventType, d.GetType(), callBack.GetType()));
}
}
//移除监听的某个方法的抛出异常方法
private static void OnListenerRemoving(EventType eventType, Delegate callBack)
{
//如果字典存在eventType
if (m_EventTable.ContainsKey(eventType))
{
Delegate d = m_EventTable[eventType];
if (d == null)
{
throw new Exception(string.Format("移除监听错误:事件{0}没有对应的委托", eventType));
}
else if (d.GetType() != callBack.GetType())
{
throw new Exception(string.Format("移除监听错误:尝试为事件{0}移除不同类型的委托,当前委托类型为{1},要移除的委托类型为{2}", eventType, d.GetType(), callBack.GetType()));
}
}
else
{
throw new Exception(string.Format("移除监听错误:没有事件码{0}", eventType));
}
}
private static void OnListenerRemoved(EventType eventType)
{
//如果字典中不存在这个类型就新建一个eventType
if (m_EventTable[eventType] == null)
{
m_EventTable.Remove(eventType);
}
}
/// <summary>
/// 监听事件的重载
/// </summary>
/// <param name="eventType"> 事件类型</param>
/// <param name="callBack"> 回调方法 </param>
//没有参数的注册方法
public static void Registered(EventType eventType, CallBack callBack)
{
OnListenerAdding(eventType, callBack);
m_EventTable[eventType] = (CallBack)m_EventTable[eventType] + callBack;
}
//一个参数的重载方法
public static void Registered<T>(EventType eventType, CallBack<T> callBack)
{
OnListenerAdding(eventType, callBack);
m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] + callBack;
}
//两个参数的重载方法
public static void Registered<T, X>(EventType eventType, CallBack<T, X> callBack)
{
OnListenerAdding(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X>)m_EventTable[eventType] + callBack;
}
//三个参数的重载方法
public static void Registered<T, X, Y>(EventType eventType, CallBack<T, X, Y> callBack)
{
OnListenerAdding(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X, Y>)m_EventTable[eventType] + callBack;
}
//四个参数的重载方法
public static void Registered<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack)
{
OnListenerAdding(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X, Y, Z>)m_EventTable[eventType] + callBack;
}
//五个参数的重载方法
public static void Registered<T, X, Y, Z, W>(EventType eventType, CallBack<T, X, Y, Z, W> callBack)
{
OnListenerAdding(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X, Y, Z, W>)m_EventTable[eventType] + callBack;
}
/// <summary>
/// 移除监听事件
/// </summary>
/// <param name="eventType">事件类型</param>
/// <param name="callBack">回调方法</param>
///
//无参数的重载移除监听方法
public static void UnRegistered(EventType eventType, CallBack callBack)
{
//判断是否存在这个类型的方法
OnListenerRemoving(eventType, callBack);
//移除这个类型中的某一个方法
m_EventTable[eventType] = (CallBack)m_EventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
//一个参数的重载监听方法
public static void UnRegistered<T>(EventType eventType, CallBack<T> callBack)
{
OnListenerRemoving(eventType, callBack);
m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
//两个参数的重载监听方法
public static void UnRegistered<T, X>(EventType eventType, CallBack<T, X> callBack)
{
OnListenerRemoving(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X>)m_EventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
//三个参数的重载移除监听方法
public static void UnRegistered<T, X, Y>(EventType eventType, CallBack<T, X, Y> callBack)
{
OnListenerRemoving(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X, Y>)m_EventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
//四个参数重载移除监听方法
public static void UnRegistered<T, X, Y, Z>(EventType eventType, CallBack<T, X, Y, Z> callBack)
{
OnListenerRemoving(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X, Y, Z>)m_EventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
//五个参数重载的移除监听方法
public static void UnRegistered<T, X, Y, Z, W>(EventType eventType, CallBack<T, X, Y, Z, W> callBack)
{
OnListenerRemoving(eventType, callBack);
m_EventTable[eventType] = (CallBack<T, X, Y, Z, W>)m_EventTable[eventType] - callBack;
OnListenerRemoved(eventType);
}
/// <summary>
/// 广播事件的方法包括重载
/// </summary>
/// <param name="eventType">事件类型</param>
//无参数 的广播方法
public static void Broadcast(EventType eventType)
{
Delegate d;
//如果字典存在这个类型的参数就返回给 d
if (m_EventTable.TryGetValue(eventType, out d))
{
//就把这个这个类型的方法赋值给callBack
CallBack callBack = d as CallBack;
//不等于空就执行方法callBack()
if (callBack != null)
{
callBack();
}
else
{
throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型", eventType));
}
}
}
//一个参数
public static void Broadcast<T>(EventType eventType, T arg)
{
Delegate d;
if (m_EventTable.TryGetValue(eventType, out d))
{
CallBack<T> callBack = d as CallBack<T>;
if (callBack != null)
{
callBack(arg);
}
else
{
throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型", eventType));
}
}
}
//两个参数
public static void Broadcast<T, X>(EventType eventType, T arg1, X arg2)
{
Delegate d;
if (m_EventTable.TryGetValue(eventType, out d))
{
CallBack<T, X> callBack = d as CallBack<T, X>;
if (callBack != null)
{
callBack(arg1, arg2);
}
else
{
throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型", eventType));
}
}
}
//三个参数
public static void Broadcast<T, X, Y>(EventType eventType, T arg1, X arg2, Y arg3)
{
Delegate d;
if (m_EventTable.TryGetValue(eventType, out d))
{
CallBack<T, X, Y> callBack = d as CallBack<T, X, Y>;
if (callBack != null)
{
callBack(arg1, arg2, arg3);
}
else
{
throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型", eventType));
}
}
}
//四个参数
public static void Broadcast<T, X, Y, Z>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4)
{
Delegate d;
if (m_EventTable.TryGetValue(eventType, out d))
{
CallBack<T, X, Y, Z> callBack = d as CallBack<T, X, Y, Z>;
if (callBack != null)
{
callBack(arg1, arg2, arg3, arg4);
}
else
{
throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型", eventType));
}
}
}
//五个参数
public static void Broadcast<T, X, Y, Z, W>(EventType eventType, T arg1, X arg2, Y arg3, Z arg4, W arg5)
{
Delegate d;
if (m_EventTable.TryGetValue(eventType, out d))
{
CallBack<T, X, Y, Z, W> callBack = d as CallBack<T, X, Y, Z, W>;
if (callBack != null)
{
callBack(arg1, arg2, arg3, arg4, arg5);
}
else
{
throw new Exception(string.Format("广播事件错误:事件{0}对应委托具有不同的类型", eventType));
}
}
}
}
然后我们看下怎么用这个事件管理系统,打开unity,新建一个脚本名字为EventCenter
然后双击打开 把上面的代码复制进去,这样方便学习,和观看
最后我们看下这个事件管理系统怎么用,因为是多个参数,用法还是和没有参数的事件一样用的,注册,广播和解注册
首先我们新建一个脚本和一个文本,Slider
我们要做的就是在slider进度条的valua达到1的时候数字加1,我们要把脚本添加到画布上面 并且打开脚本
在脚本中把要文本获取到,然后把进度条slider获取到,把要注册的类型和广播要做的事情写好,直接上代码
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEditor;
public class Tets : MonoBehaviour
{
//计数器
int count;
//进度条
Slider S;
//文本
Text c;
// Start is called before the first frame update
void Start()
{
//寻找文本
c = this.transform.Find("Text").GetComponent<Text>();
count = 0;
//寻找进度条
Transform tmp = this.transform.Find("Slider");
S = tmp.GetComponent<Slider>();
//进度条的value初始化为1
S.value = 0;
//监听改变文本数值的事件
EventCenter.Registered<int, int>(EventType.ShowText, Show);
}
//回调方法
void Show(int a,int v)
{
c.text =( a + v).ToString();
}
// Update is called once per frame
void Update()
{
S.value += 0.01f;
//当进度条的数字为1的时候就让文本数字+1
if (S.value==1)
{
count++;
EventCenter.Broadcast(EventType.ShowText,count ,3);
S.value = 0;
}
}
}
当然在这之前用监听文本之前要在
事件枚举类型中添加一个枚举放到自己写的注册方法中
然后在调用的时候广播方法中把类型传进去
然后我们运行就可以了
有什么不了解的可以私信我,希望对大家有帮助