Unity游戏框架设计之事件管理器

本文介绍了Unity游戏开发中如何通过事件管理器解决代码耦合问题,利用发布订阅模式设计事件中心,实现事件的订阅、发布和取消订阅,强调了生命周期管理和命名规范的重要性。
摘要由CSDN通过智能技术生成

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))
        {
            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))
        {
            return;
        }
        Action<EventData> actionSet = EventCenter[eventKey];
        if (actionSet is null || actionSet.GetInvocationList().Length == 0)
        {
            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() 中取消订阅,否则可能导致事件发布时由于没有取消订阅导致错误处理的问题。

后记

由于个人能力有限,文中不免存在疏漏之处,恳求大家斧正,一起交流,共同进步。

  • 11
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
UNITY游戏框架原理基于MVC的逻辑模式。MVC是一种在制作游戏时对代码的逻辑化整理的思想。在UNITY开发过程中,许多公司在制作游戏开发项目时都使用了MVC的逻辑模式,即数据模型-视图-控制器。 UNITY游戏框架可以分为三个主要部分。第一部分是游戏开发的基础,包括游戏的架构设计、场景管理和资源管理等。第二部分是网络原理,主要介绍网络通信的原理,开发客户端的网络模块和服务端程序框架。这套框架具有较高的通用性,可用于多种游戏。第三部分是网络游戏,主要讲解房间系统和多人游戏的开发。 在设计UNITY游戏框架时,可以考虑采用MVC的结构模式,将模块之间的功能区分开,达到低耦合的效果。这样做的好处是,当需要替换游戏UI或进行其他功能修改时,只需修改相应的模块,而不会影响到其他功能,提高了游戏质量和开发效率。举个例子,如果一个项目的各个UI下挂载了大量的脚本,替换UI可能会导致其他功能受到影响,而采用MVC的结构模式可以解决这个问题。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [Unity框架——MVC框架](https://blog.csdn.net/Htlas/article/details/79076201)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* [Unity 3D网络游戏实战](https://download.csdn.net/download/qq_39014199/11143402)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值