UFL4-2——事件中心传递参数
事件中心中传递参数指的是什么
希望在触发事件时传递数据,比如
- 怪物死亡时,将怪物信息传递出去
- 获取奖励时,将奖励信息传递出去
等等
传递数据的主要目的是,我们可以在各系统、模块、对象中获取到我们希望获取的有用信息
制作思路和具体实现
我们目前触发事件,是通过执行委托中存储的函数来执行各系统对应的逻辑,那么需要传递参数,我们很自然的联想到应该从委托入手
但是参数的类型可能有多种多样,我们可以采用万物之父 object
利用里式替换原则,父类容器装载子类对象的方式来传递参数
因此,将存储事件的委托字典eventDic
的值从UnityAction
转为使用UnityAction<object>
,
其他相关方法AddEventListener
和RemoveEventListener
也修改为使用UnityAction<object>
参数,
而触发事件的方法EventTrigger
就需要额外传入一个object
参数,在执行委托时将参数传进去
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| private Dictionary<string, UnityAction<object>> eventDic = new Dictionary<string, UnityAction<object>>();
private EventCenter() { }
public void EventTrigger(string eventName, object info = null) { if (!eventDic.ContainsKey(eventName)) return; eventDic[eventName]?.Invoke(info); }
public void AddEventListener(string eventName, UnityAction<object> action) { if (eventDic.ContainsKey(eventName)) eventDic[eventName] += action; else { eventDic.Add(eventName, null); eventDic[eventName] += action; } }
public void RemoveEventListener(string eventName, UnityAction<object> action) { if (eventDic.ContainsKey(eventName)) eventDic[eventName] -= action; }
|
使用示例
这样 Monster
类就可以在触发事件时,将自己作为参数传递到各个监听者,监听者即可获取怪物的消息
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| using UnityEngine;
public class Monster : MonoBehaviour { public string monsterName = "123123123"; public int monsterID = 1;
public void Dead() { Debug.Log("怪物死亡了"); EventCenter.Instance.EventTrigger("MonsterDead", this); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| using UnityEngine;
public class Player : MonoBehaviour { private void Awake() { EventCenter.Instance.AddEventListener("MonsterDead", PlayerWaitMonsterDeadDo); }
public void PlayerWaitMonsterDeadDo(object info) { Monster monster = info as Monster; Debug.Log("怪物名为:" + monster.monsterName + ",怪物ID" + monster.monsterID); Debug.Log("玩家得到奖励"); }
public void OnDestroy() { EventCenter.Instance.RemoveEventListener("MonsterDead", PlayerWaitMonsterDeadDo); } }
|
输出:
存在的问题
使用 object
进行参数传递,当传递值类型数据时,会存在装箱拆箱,增加性能开销
可传入参数的事件中心具体代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
| using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Events;
public class EventCenter : BaseManager<EventCenter> { private Dictionary<string, UnityAction<object>> eventDic = new Dictionary<string, UnityAction<object>>();
private EventCenter() { }
public void EventTrigger(string eventName, object info = null) { if (!eventDic.ContainsKey(eventName)) return; eventDic[eventName]?.Invoke(info); }
public void AddEventListener(string eventName, UnityAction<object> action) { if (eventDic.ContainsKey(eventName)) eventDic[eventName] += action; else { eventDic.Add(eventName, null); eventDic[eventName] += action; } }
public void RemoveEventListener(string eventName, UnityAction<object> action) { if (eventDic.ContainsKey(eventName)) eventDic[eventName] -= action; }
public void Clear() { eventDic.Clear(); }
public void Clear(string eventName) { if (eventDic.ContainsKey(eventName)) eventDic.Remove(eventName); } }
|