Unity游戏框架设计之任务管理器
简单介绍
在游戏开发中,我们可能会遇到下述需求。当角色的生命值减少时,我们需要让角色播放受伤动画,让系统播放角色受伤音效,将当前的新的生命值更新到 UI 上等等操作。如果在角色的代码中直接实现上述的操作,则将导致代码的高度耦合,不利于后期的维护和拓展。
为解决上面的问题,我们可以认为,当角色的生命值减少时,实际上会发布角色生命值减少事件,然后让订阅角色生命值减少事件的子系统分别处理此事件,这就是事件管理器的核心功能。
事件管理器基于发布订阅模式实现。通过发布与订阅功能,可以实现事件的发布者和订阅者之间解耦合,并提高代码的可维护性。
代码设计
public class EventManager : SingletonMono<EventManager>
{
private static readonly Dictionary<string, Action<EventData>> EventCenter = new();
public void Subscribe(string eventKey, Action<EventData> handler)
{
if (!EventCenter.TryAdd(eventKey, handler))
{
EventCenter[eventKey] += handler;
}
}
public void Unsubscribe(string eventKey, Action<EventData> handler)
{
if (!EventCenter.ContainsKey(eventKey))
{
LogManager.Instance.DebugWarning($"不存在此事件。eventKey={eventKey}");
return;
}
EventCenter[eventKey] -= handler;
if (EventCenter[eventKey] == null || EventCenter[eventKey].GetInvocationList().Length == 0)
{
EventCenter.Remove(eventKey);
}
}
public void Publish(string eventKey, EventData eventData)
{
if (!EventCenter.ContainsKey(eventKey))
{
LogManager.Instance.DebugLog($"事件没有被处理。eventKey={eventKey},eventData={eventData}");
return;
}
Action<EventData> actionSet = EventCenter[eventKey];
if (actionSet is null || actionSet.GetInvocationList().Length == 0)
{
LogManager.Instance.DebugWarning($"发布事件失败。没有事件处理器处理此事件。eventKey={eventKey},eventData={eventData}");
return;
}
foreach (Delegate action in actionSet.GetInvocationList())
{
try
{
action.DynamicInvoke(eventData);
}
catch (Exception e)
{
LogManager.Instance.DebugWarning(e.ToString());
}
}
}
public abstract class EventData
{
}
public class EmptyEventData : EventData
{
}
public class NormalEventData<T> : EventData
{
public readonly T Data;
public NormalEventData(T data)
{
Data = data;
}
}
}
代码说明
(一)实现事件的订阅与发布功能。
(二)eventKey 推荐格式为 public static readonly string {FieldName} = "{ClassName}{FieldName}";
不推荐添加 ID 后缀。
(三)handler 参数传递的事件函数推荐以 OnXXX 作为前缀。
(四)订阅方法 Subscribe() 必须与取消订阅方法 Unsubscribe() 配对使用。如果在 Awake()/OnEnable()/Start() 中调用 Subscribe(),则必须在 OnDisable()/OnDestroy() 中取消订阅,否则可能导致事件发布时由于没有取消订阅导致错误处理的问题。
后记
由于个人能力有限,文中不免存在疏漏之处,恳求大家斧正,一起交流,共同进步。
标签:EventCenter,订阅,管理器,框架,Unity,handler,eventKey,public,事件 From: https://www.cnblogs.com/kkelin/p/18166803