[Unity 3D] ET 框架网络模块的抽离、重构与模块化

ET介绍

一个双端 C# Unity 游戏开发框架,网络 + 热重载的功能亮点; Attribute + 扩展方法 + 反射的底层驱动逻辑;ECS 架构特色。

前言

做一个飞屏软件,负责技术的同事敲定用 ET ,emmm… 内心是抗拒的,毕竟项目不大,但反过来想想,项目不大正好是个学习 ET 的契机。
因为我负责控制端,用不到热更,并且习惯了在 Unity 内做开发,所以我决定把 ET 的网络模块剥离出来,用在我负责的控制端上,这样一来,既能够与 ET 后台对接,也能保持我自己的开发习惯。

当然,非要说细节上为啥抗拒,其实是有几点的,作为 ET 0 基础小白斗胆小声BB几句:

1、为了热重载,严格约束用户按照 ET ECS 架构开发,因此开发一个应用得整好几个解决方案,而且还不是常规的打开方式,跨解决方案的引用查找还挺难(可能是我太菜哈)。
2、不需要热更,ILRuntime 插件冗余了,不能忍,如果考虑热更那也只会是对现有开发模式无侵入的 HCLR。
3、修改在 Model 、 Hotfix 程序集,需要编译才能看到修改的效果,而开启自动编译一度让我困惑。
4、框架文件结构限定的比较死,由于很多路径都是写死在逻辑中,原本仅有一个 Server ,一个 Client,想要做 一个 Server + 两个 Client 令初次接触 ET 的我无从下手(当然,现在整明白了,改一些脚本中文件夹路径就行,按说 ET7 啥都内敛到了 Unity 内部,也不预设热更方案也就没有这些痛点了)。

抽离

1、更新 ET6.0 Github最新提交后,一通复制粘贴,把网络部分梳理到新工程中
2、转移 Protobuf、Litjson 、ETTask、Timer 、KCP 到新工程。
3、删除 Litjson 、Protobuf 中为适配 ILRuntime 而撰写的逻辑。
4、此时,网络模块已经大体抽离,然后再根据报错,将缺失的、离散在周边的脚本汇集整理。
5、到了这一步,网络模块还是 ECS 架构的(由于模块无需热更, ECS 没有拆分在各个程序集)所以一通改造,把各个功能模块的 ECS 整合成单脚本(其实就是把 Component的字段,System 中的 Awake 、Update 等方法整到一起,使用 MonoBehaviour 驱动)。
6、ET EventSystem ,ET 的心脏,用于在启动或热重载时根据 Attribute 做 Type 预绑定,同时也是一个事件总线。网络模块、ECS以及事件分发都依赖它,一通删除,保留网络消息类型注册部分即可。
7、断开对 ET Entity 的依赖:删除继承关系,同时将 GetChild 、AddChild 进行简单的改写成实例查询和实例构建就好了。
8、两个有意思的地方:LitJson 保留是为了 网络消息实例以 json 输出,方便log;KCP 最后被干掉了是因为 ET6.0 为了通用,即便是 KServer 、KChannel 也默认不使用 KCP。

重构

1、管理器性质的组件都依赖了 MonoBehaviour 驱动,但他们多为管理器性质,所以笔者将他们改为静态类。
2、对管理器性质的组件的初始化放在 ET Eventsystem 中统一按顺序进行(比如 opcode管理器就要优先于其他消息分发管理器)。
3、对管理器性质的组件的 Update 统一放在 ET Eventsystem 中统一使用 PlayerLoop 驱动。
4、作为底层核心网络消息,将 Ping 消息 OuterMessage 中单独抽离出来,实现网络模块对 OuterMessage 零依赖。
5、重新设计非 RPC 网络消息的监听与取消监听,实现非 RPC 消息在继承了 MonoBehaviour 的类更方便的被捕获。
6、代码生成:实现非RPC 网络消息处理器的一键生成;修正 OuterMessage 的一键生成逻辑,跳过 Ping 消息。
7、引入 Loom 做线程间数据传递,剔除原有的带 Thread 关键字的组件,避免了不必要的依赖注入,使用 using static Loom;的形式简化多线程间数据的投递。

模块化

借助 Unity 官方 Assembly Definition File ,我们可以在 Unity 项目中轻松的模块化 ET 网络模块。

首先,将依赖的插件抽离,放在 ThirdPart,为他们加上各自的 .asmdef 文件,使其模块化

然后,将用户自定义的消息类 (OuterMessage.cs 和 OuterOpcode.cs)抽离,网络模块对其 0 依赖,方便随时剔除,随时生成,随时更新。

网络模块重构成以下形式:

在这里插入图片描述

可见:

ettask 、timer 、litjson、protobuf 都成了独立的程序集。

网络核心又拆分出 editor + runtime + generated(generated 为一键生成的 outermessage 和 messagehandler)

使用

1、clone 本项目,将文件夹 ET Network Module 拷贝到你的项目中(可考虑自行改为 UPM )
2、删除 Generated 文件夹。
3、如果有代码引用了 OuterMessage 中的类型,则这个代码所在的文件夹改名,加上 ~ (波浪号)完成编译后再删除波浪号
4、约定:前后端公用的 outermessage.proto 中 Ping 消息置顶。
5、通过 Tools 菜单中提供的工具,依次生成 OuterMessage.cs 、OuterOpcode.cs 以及各个非 RPC 消息处理器
6、调用 ET 原生 API:call + send 实现通信,var response = await Session.call(new SomeRPCRequest()) 或者 Session.Send(new NoRPCRequest())
7、非 RPC 消息的监听:使用 using static MessageHandler 即可在自己的类中通过 ListenSignal 、RemoveSignal 处理感兴趣的网络消息,示例代码如下:

using ET;
using UnityEngine;
using static MessageHandler;
public class HandlerUsageCase : MonoBehaviour
{
    private void Start()
    {
        ListenSignal<M2C_CreateMyUnit>(OnMyUnitCreated);
        ListenSignal<M2C_CreateUnits>(OnUnitsCreated);
    }

    private void OnUnitsCreated(Session arg1, M2C_CreateUnits arg2)
    {
        // 撰写你自己的逻辑
    }
    private void OnMyUnitCreated(Session arg1, M2C_CreateMyUnit arg2)
    {
        // 撰写你自己的逻辑
    }
    private void OnDestroy()
    {
        RemoveSignal<M2C_CreateMyUnit>(OnMyUnitCreated);
        RemoveSignal<M2C_CreateUnits>(OnUnitsCreated);
    }
}

演示

演示一:消息生成,消息处理器生成

在这里插入图片描述

演示二:测试与 ET 服务器通信(登录网关,登录地图,Ping(心跳))

在这里插入图片描述

写到最后

1、为了方便的测试此 ET 网络模块,提供 ET6.0 示例 Server 编译而来的 .exe 文件,通过菜单 “Tools/Start Test Server” 开启。
2、需要留意的是,因为彻底的重构,导致了业务逻辑代码必不可能复用,所以 ET 服务器的 AI压测、AI陪玩啥的怕是用不了,这点大家应该是明了的。
3、本文配套项目地址:https://github.com/Bian-Sh/ET-Network-Module

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大号叉裆裤

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值