Unity游戏开发之设计模式之事件分发系统

Unity游戏开发 — 事件系统

记得刚刚毕业时候,上班的第一天,主程就给我讲了游戏开发中最常见的几种设计模式,当时听得一头雾水。只知道事件分发,事件监听,事件注册。那么到底是怎么实现的呢?下面我们慢慢的揭开它。

  1. 先了解一下什么是委托。这是C#基础,这里就不在陈述了。

  2. 了解什么观察者模式。简单的说:就是完美的将观察者和被观察的对象分离开,观察者设计模式定义了对象间的一种一对多的组合关系,以便一个对象的状态发生变化时,所有依赖于它的对象都得到通知并自动刷新。

游戏事件系统

unity的事件系统就是根据上面的组合现实的。

  1. 添加事件注册`
 private void AddDelegate(int evt, Delegate listener)
  {
      Delegate value;
      if (!listeners.TryGetValue(evt, out value))
      {
          listeners.Add(evt, listener);
      }
      else
      {
          value = (value != null) ? Delegate.Combine(value, listener) : listener;
          listeners[evt] = value;
      }
  }

  1. 移除事件
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;
           }
       }
   }
  1. 事件触发
 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);
        }
    }

基本就是上面的这三个步骤;

这是源代码

using System;
using System.Collections.Generic;

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
{
    private Dictionary<int, Delegate> listeners = new Dictionary<int, Delegate>();

    public EventDispatcher()
    {
    }

    public void ClearEventListener()
    {
        listeners.Clear();
    }

    private void AddDelegate(int evt, Delegate listener)
    {
        Delegate value;
        if (!listeners.TryGetValue(evt, out value))
        {
            listeners.Add(evt, listener);
        }
        else
        {
            value = (value != null) ? Delegate.Combine(value, listener) : listener;
            listeners[evt] = value;
        }
    }

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

    public void Regist(int evt, Act listener)
    {
        if (listener == null)
        {
            return;
        }

        AddDelegate(evt, listener);
    }

    public void UnRegist(int evt, Act listener)
    {
        if (listener == null)
        {
            return;
        }

        RemoveDelegate(evt, listener);
    }

    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 (Exception e)
        {
            UnityEngine.Debug.LogError(e.Message);
            UnityEngine.Debug.LogError(e.StackTrace);
        }

        return default(T);
    }

    public void RegistFn<T, T1>(int evt, Fn<T, T1> listener)
    {
        if (listener == null)
        {
            return;
        }

        AddDelegate(evt, listener);
    }

    public void UnRegistFn<T, T1>(int evt, Fn<T, T1> listener)
    {
        if (listener == null)
        {
            return;
        }

        RemoveDelegate(evt, listener);
    }

    public T DispatchEventFn<T, T1>(int evt, T1 args)
    {
        Delegate func;

        try
        {
            if (listeners.TryGetValue(evt, out func) && func != null)
            {
                var tmp = (Fn<T, T1>)func;
                return tmp(args);
            }
        }
        catch (Exception e)
        {
            UnityEngine.Debug.LogError(e.Message);
            UnityEngine.Debug.LogError(e.StackTrace);
        }

        return default(T);
    }

    public void RegistFn<T, T1, T2>(int evt, Fn<T, T1, T2> listener)
    {
        if (listener == null)
        {
            return;
        }

        AddDelegate(evt, listener);
    }

    public void UnRegistFn<T, T1, T2>(int evt, Fn<T, T1, T2> listener)
    {
        if (listener == null)
        {
            return;
        }

        RemoveDelegate(evt, listener);
    }

    public T DispatchEventFn<T, T1, T2>(int evt, T1 arg1, T2 arg2)
    {
        Delegate func;

        try
        {
            if (listeners.TryGetValue(evt, out func) && func != null)
            {
                var fn = (Fn<T, T1, T2>)func;
                return fn(arg1, arg2);
            }
        }
        catch (Exception e)
        {
            UnityEngine.Debug.LogError(e.Message);
            UnityEngine.Debug.LogError(e.StackTrace);
        }

        return default(T);
    }

    public void RegistFn<T, T1, T2, T3>(int evt, Fn<T, T1, T2, T3> listener)
    {
        if (listener == null)
        {
            return;
        }

        AddDelegate(evt, listener);
    }

    public void UnRegistFn<T, T1, T2, T3>(int evt, Fn<T, T1, T2, T3> listener)
    {
        if (listener == null)
        {
            return;
        }

        RemoveDelegate(evt, listener);
    }

    public T DispatchEventFn<T, T1, T2, T3>(int evt, T1 arg1, T2 arg2, T3 arg3)
    {
        Delegate func;

        try
        {
            if (listeners.TryGetValue(evt, out func) && func != null)
            {
                var fn = (Fn<T, T1, T2, T3>)func;
                return fn(arg1, arg2, arg3);
            }
        }
        catch (Exception e)
        {
            UnityEngine.Debug.LogError(e.Message);
            UnityEngine.Debug.LogError(e.StackTrace);
        }

        return default(T);
    }

    public void RegistFn<T, T1, T2, T3, T4>(int evt, Fn<T, T1, T2, T3, T4> listener)
    {
        if (listener == null)
        {
            return;
        }

        AddDelegate(evt, listener);
    }

    public void UnRegistFn<T, T1, T2, T3, T4>(int evt, Fn<T, T1, T2, T3, T4> listener)
    {
        if (listener == null)
        {
            return;
        }
        RemoveDelegate(evt, listener);
    }

    public T DispatchEventFn<T, 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 fn = (Fn<T, T1, T2, T3, T4>)func;
                return fn(arg1, arg2, arg3, arg4);
            }
        }
        catch (Exception e)
        {
            UnityEngine.Debug.LogError(e.Message);
            UnityEngine.Debug.LogError(e.StackTrace);

        }

        return default(T);
    }

    static EventDispatcher GameWorldEventDispatcher = new EventDispatcher();

    public static EventDispatcher GameEvent
    {
        get
        {
            return GameWorldEventDispatcher;
        }
    }
}

在游戏需要调用的地方在这里插入图片描述
最后说一下在游戏退出后执行一下

 public void ClearEventListener()
    {
        listeners.Clear();
    }
  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值