首先,这篇博文是参考了
http://blog.sina.com.cn/s/blog_5b6cb9500102uypp.html
这个文章作者的思路而设计的。经过自己的理解后,模仿了一个消息系统给自己用,下面谈谈对这个系统的认识和看法。
我所制作的EventManager的核心是:
1.把我们游戏中所有用到的方法,全部放在一个枚举中,如下:
public enum GameEvent
{
//这里是定义玩家的事件
PLAYER_ATTACK,
PLAYER_DEATH,
PLAYER_SPEAK,
PLAYER_GAINLIFE,
PLAYER_REDUCELIFE,
//这里是定义怪物的事件
ENEMY_DEATH,
ENEMY_ATTACK,
ENEMY_REDUCELIFE,
}
2.建立一个字典容器,然后在游戏初始化的时候把游戏中所有的事件即上面的GameEvent全部保存在字典的key中,这样我们就把游戏内所有的事件名全部放在了一个字典中。代码如下:
//建立委托
public delegate void CommonEvent(object data);
//建立事件列表
public Dictionary<GameEvent, CommonEvent> eventDic = new Dictionary<GameEvent, CommonEvent>();
/// <summary>
/// 事件初始化
/// </summary>
public void InitEvent()
{
foreach (GameEvent key in Enum.GetValues(typeof(GameEvent)))
{
AddEvent(key);
}
}
/// <summary>
/// 添加一个回调事件
/// </summary>
/// <param name="key"></param>
void AddEvent(GameEvent key)
{
eventDic.Add(key, delegate (object data) { });
}
3.我们给这个类添加3个行为,分别是注册事件,执行事件,解绑事件。它们的作用就是我们在游戏中将所有需要实体和对象,当他们需要和其他对象进行交互的时候,我们首先将所有对象的每一个交互行为添加在GameEvent枚举中,然后在这些对象进行初始化的时候,把这个对象的行为利用EventManager的注册方法注册进入字典中;在对象需要相互交互的时候,我们直接调用EventManager的执行事件调用相应的方法;在对话被销毁的时候我们执行EventManager的解绑事件方法,如下:
/// <summary>
/// 触发事件
/// </summary>
/// <param name="key"></param>
/// <param name="param"></param>
public void TriggerEvent(GameEvent key,object param)
{
if (eventDic.ContainsKey(key))
{
eventDic[key](param);
}
else
{
Debug.LogError("没有定义的事件:" + key);
}
}
/// <summary>
/// 绑定一个事件
/// </summary>
/// <param name="key">事件的key</param>
/// <param name="attachEvent">事件的方法</param>
public void AttachEvent(GameEvent key , CommonEvent attachEvent)
{
if (eventDic.ContainsKey(key))
{
eventDic[key] += attachEvent;
}
else
{
Debug.LogError("没有定义的事件:" + key);
}
}
/// <summary>
/// 解绑一个事件
/// </summary>
/// <param name="key">事件的key</param>
/// <param name="detachEvent">要解除的事件方法</param>
public void DetachEvent(GameEvent key , CommonEvent detachEvent)
{
if (eventDic.ContainsKey(key))
{
eventDic[key] -= detachEvent;
}
else
{
Debug.LogError("没有定义的事件:" + key);
}
}
以下是完整代码:
using UnityEngine;
using System;
using System.Collections;
using System.Collections.Generic;
public enum GameEvent
{
//这里是定义玩家的事件
PLAYER_ATTACK,
PLAYER_DEATH,
PLAYER_SPEAK,
PLAYER_GAINLIFE,
PLAYER_REDUCELIFE,
//这里是定义怪物的事件
ENEMY_DEATH,
ENEMY_ATTACK,
ENEMY_REDUCELIFE,
}
public class EventManager{
private static EventManager _instance;
public static EventManager Instance
{
get
{
if(_instance == null)
{
_instance = new EventManager();
}
return _instance;
}
}
//建立委托
public delegate void CommonEvent(object data);
//建立事件列表
public Dictionary<GameEvent, CommonEvent> eventDic = new Dictionary<GameEvent, CommonEvent>();
/// <summary>
/// 事件初始化
/// </summary>
public void InitEvent()
{
foreach (GameEvent key in Enum.GetValues(typeof(GameEvent)))
{
AddEvent(key);
}
}
/// <summary>
/// 添加一个回调事件
/// </summary>
/// <param name="key"></param>
void AddEvent(GameEvent key)
{
eventDic.Add(key, delegate (object data) { });
}
/// <summary>
/// 触发事件
/// </summary>
/// <param name="key"></param>
/// <param name="param"></param>
public void TriggerEvent(GameEvent key,object param)
{
if (eventDic.ContainsKey(key))
{
eventDic[key](param);
}
else
{
Debug.LogError("没有定义的事件:" + key);
}
}
/// <summary>
/// 绑定一个事件
/// </summary>
/// <param name="key">事件的key</param>
/// <param name="attachEvent">事件的方法</param>
public void AttachEvent(GameEvent key , CommonEvent attachEvent)
{
if (eventDic.ContainsKey(key))
{
eventDic[key] += attachEvent;
}
else
{
Debug.LogError("没有定义的事件:" + key);
}
}
/// <summary>
/// 解绑一个事件
/// </summary>
/// <param name="key">事件的key</param>
/// <param name="detachEvent">要解除的事件方法</param>
public void DetachEvent(GameEvent key , CommonEvent detachEvent)
{
if (eventDic.ContainsKey(key))
{
eventDic[key] -= detachEvent;
}
else
{
Debug.LogError("没有定义的事件:" + key);
}
}
}
——————2017.03.31更新——————————————
上文中的EventManager是一个多播委托。比如说我们游戏中有多个怪物的实例,若我们触发了怪物的死亡事件,那么所有的怪物都会执行相应的死亡方法。此时,必须在怪物的死亡方法中做if条件判断,来判断自己是否达到了死亡条件。若不做判断,则会立即死亡。
因此,在有多个实例的时候,在通知实例执行一定的方法时,必须设置好充分的条件判断,这样才不会出问题。