Unity C# 游戏开发 事件 消息派发器(图文详细,带源码)
Posted 水光涵月
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity C# 游戏开发 事件 消息派发器(图文详细,带源码)相关的知识,希望对你有一定的参考价值。
Unity C# 游戏开发 事件 消息派发器 (图文详细,带源码)
事情是这样的
可可爱爱的程序媛小姐姐又来找我玩啦,本来是开心的聊天却变成了技术研讨会,小姐姐说最近敲代码,各种事件委托,各种观察者模式,手都敲麻了,问我有好办法没有
那我可以帮你揉一下?(显然不符合我钢铁直男的人设),那就写个消息派发器来帮助小姐姐吧!
一、消息派发器的几个功能
既然是要来简化观察者模式,那功能肯定一个都不能少
1.添加事件注册
需要2个参数,第一个是索引,第二个是事件
/// <summary>
/// 添加事件注册
/// </summary>
/// <param name="evt">索引</param>
/// <param name="listener"></param>
private void AddDelegate(int evt, Delegate listener)
{
Delegate value;
if (!listeners.TryGetValue(evt, out value))
{
//key不存在就添加
listeners.Add(evt, listener);
}
else
{
//key存在判断value是否为空,为空就替换,不为空就多播
value = (value != null) ? Delegate.Combine(value, listener) : listener;
listeners[evt] = value;
}
}
2.事件的触发
事件的触发需要传入一个 索引
/// <summary>
/// 事件触发
/// </summary>
/// <param name="evt"></param>
public void DispatchEvent(int evt)
{
Delegate func;
try
{
if (listeners.TryGetValue(evt, out func) && func != null)
{
var act = (Act)func;
act();
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(e.Message);
UnityEngine.Debug.LogError(e.StackTrace);
}
}
3.移除事件
事件移除和注册需要的参数是一样的
/// <summary>
/// 移除事件
/// </summary>
/// <param name="evt"></param>
/// <param name="listener"></param>
private void RemoveDelegate(int evt, Delegate listener)
{
Delegate func;
if (listeners.TryGetValue(evt, out func))
{
if (func != null)
{
func = Delegate.Remove(func, listener);
listeners[evt] = func;
}
else
{
Debug.LogError("Key" + evt + "不存在!");
}
}
}
二、完整代码
using System;
using System.Collections.Generic;
using UnityEngine;
public delegate void Act();
public delegate void Act<in T>(T t1);
public delegate void Act<in T1, in T2>(T1 t1, T2 t2);
public delegate void Act<in T1, in T2, in T3>(T1 t1, T2 t2, T3 t3);
public delegate void Act<in T1, in T2, in T3, in T4>(T1 t1, T2 t2, T3 t3, T4 t4);
public delegate T Fn<out T>();
public delegate T Fn<out T, in T1>(T1 t1);
public delegate T Fn<out T, in T1, in T2>(T1 t1, T2 t2);
public delegate T Fn<out T, in T1, in T2, in T3>(T1 t1, T2 t2, T3 t3);
public delegate T Fn<out T, in T1, in T2, in T3, in T4>(T1 t1, T2 t2, T3 t3, T4 t4);
public class EventDispatcher
{
/// <summary>
/// 字典存放
/// </summary>
private Dictionary<int, Delegate> listeners = new Dictionary<int, Delegate>();
public static EventDispatcher GameWorldEventDispatcher = new EventDispatcher();
/// <summary>
/// 单例模式
/// </summary>
public static EventDispatcher GameEvent
{
get
{
return GameWorldEventDispatcher;
}
}
/// <summary>
/// 构造函数
/// </summary>
public EventDispatcher()
{
}
/// <summary>
/// 移除字典中所有的键值(解绑所有事件)
/// </summary>
public void ClearEventListener()
{
listeners.Clear();
}
/// <summary>
/// 添加事件注册
/// </summary>
/// <param name="evt">索引</param>
/// <param name="listener"></param>
private void AddDelegate(int evt, Delegate listener)
{
Delegate value;
if (!listeners.TryGetValue(evt, out value))
{
//key不存在就添加
listeners.Add(evt, listener);
}
else
{
//key存在判断value是否为空,为空就替换,不为空就多播
value = (value != null) ? Delegate.Combine(value, listener) : listener;
listeners[evt] = value;
}
}
/// <summary>
/// 移除事件
/// </summary>
/// <param name="evt"></param>
/// <param name="listener"></param>
private void RemoveDelegate(int evt, Delegate listener)
{
Delegate func;
if (listeners.TryGetValue(evt, out func))
{
if (func != null)
{
func = Delegate.Remove(func, listener);
listeners[evt] = func;
}
else
{
Debug.LogError("Key" + evt + "不存在!");
}
}
}
/// <summary>
/// 注册
/// </summary>
/// <param name="evt"></param>
/// <param name="listener"></param>
public void Regist(int evt, Act listener)
{
if (listener == null)
{
return;
}
AddDelegate(evt, listener);
}
/// <summary>
/// 移除
/// </summary>
/// <param name="evt"></param>
/// <param name="listener"></param>
public void UnRegist(int evt, Act listener)
{
if (listener == null)
{
return;
}
RemoveDelegate(evt, listener);
}
/// <summary>
/// 事件触发
/// </summary>
/// <param name="evt"></param>
public void DispatchEvent(int evt)
{
Delegate func;
try
{
if (listeners.TryGetValue(evt, out func) && func != null)
{
var act = (Act)func;
act();
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(e.Message);
UnityEngine.Debug.LogError(e.StackTrace);
}
}
public void Regist<T>(int evt, Act<T> listener)
{
if (listener == null)
{
return;
}
AddDelegate(evt, listener);
}
public void UnRegist<T>(int evt, Act<T> listener)
{
if (listener == null)
{
return;
}
RemoveDelegate(evt, listener);
}
public void DispatchEvent<T1>(int evt, T1 args)
{
Delegate func;
if (listeners.TryGetValue(evt, out func) && func != null)
{
var act = (Act<T1>)func;
act(args);
}
}
public void Regist<T1, T2>(int evt, Act<T1, T2> listener)
{
if (listener == null)
{
return;
}
AddDelegate(evt, listener);
}
public void UnRegist<T1, T2>(int evt, Act<T1, T2> listener)
{
if (listener == null)
{
return;
}
RemoveDelegate(evt, listener);
}
public void DispatchEvent<T1, T2>(int evt, T1 arg1, T2 arg2)
{
Delegate func;
try
{
if (listeners.TryGetValue(evt, out func) && func != null)
{
var tmp = (Act<T1, T2>)func;
tmp(arg1, arg2);
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(e.Message);
UnityEngine.Debug.LogError(e.StackTrace);
}
}
public void Regist<T1, T2, T3>(int evt, Act<T1, T2, T3> listener)
{
if (listener == null)
{
return;
}
AddDelegate(evt, listener);
}
public void UnRegist<T1, T2, T3>(int evt, Act<T1, T2, T3> listener)
{
if (listener == null)
{
return;
}
RemoveDelegate(evt, listener);
}
public void DispatchEvent<T1, T2, T3>(int evt, T1 arg1, T2 arg2, T3 arg3)
{
Delegate func;
try
{
if (listeners.TryGetValue(evt, out func) && func != null)
{
var tmp = (Act<T1, T2, T3>)func;
tmp(arg1, arg2, arg3);
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(e.Message);
UnityEngine.Debug.LogError(e.StackTrace);
}
}
public void Regist<T1, T2, T3, T4>(int evt, Act<T1, T2, T3, T4> listener)
{
if (listener == null)
{
return;
}
AddDelegate(evt, listener);
}
public void UnRegist<T1, T2, T3, T4>(int evt, Act<T1, T2, T3, T4> listener)
{
if (listener == null)
{
return;
}
RemoveDelegate(evt, listener);
}
public void DispatchEvent<T1, T2, T3, T4>(int evt, T1 arg1, T2 arg2, T3 arg3, T4 arg4)
{
Delegate func;
try
{
if (listeners.TryGetValue(evt, out func) && func != null)
{
var tmp = (Act<T1, T2, T3, T4>)func;
tmp(arg1, arg2, arg3, arg4);
}
}
catch (Exception e)
{
UnityEngine.Debug.LogError(e.Message);
UnityEngine.Debug.LogError(e.StackTrace);
}
}
public void RegistFn<T>(int evt, Fn<T> listener)
{
if (listener == null)
{
return;
}
AddDelegate(evt, listener);
}
public void UnRegistFn<T>(int evt, Fn<T> listener)
{
if (listener == null)
{
return;
}
RemoveDelegate(evt, listener);
}
public T DispatchEventFn<T>(int evt)
{
Delegate func;
try
{
if (listeners.TryGetValue(evt, out func) && func != null)
{
var fn = (Fn<T>)func;
return fn();
}
}
catch (以上是关于Unity C# 游戏开发 事件 消息派发器(图文详细,带源码)的主要内容,如果未能解决你的问题,请参考以下文章
转UNITY3D 游戏开发之七C# 中的委托事件匿名函数Lambda 表达式
错误记录Visual Studio 2019 中运行 Unity C# 脚本时报错 ( 根据解决方案, 可能需要安装额外的组件才能获得 | .NET 桌面开发 | 使用 Unity 的游戏开发 )