ET 框架中 ECS 的作用与核心技术实现解析
ET 框架通过严格的ECS(Entity-Component-System)架构重构了游戏开发模式,其核心作用在于彻底解耦数据与逻辑,实现前后端代码高度复用及高性能热更新。以下是基于文档内容的深度解析:
1. ECS 的核心作用与设计原则
在 ET 框架中,ECS 不仅仅是设计模式,更是强制性的编码规范,旨在消除传统面向对象编程(OOP)中的继承耦合与虚函数开销。
| 核心概念 | 作用与定义 | 存放规范 (文件夹) | 关键约束与实现细节 |
|---|---|---|---|
| Entity (实体) | 数据容器。游戏中的对象(如角色、道具),本质是组件的集合。“实体即组件,组件即实体”。 | Model/ModelView | 1. 只能继承Entity基类,严禁继承其他类。2. 必须实现生命周期接口 ( IAwake,IDestroy) 以管理对象池回收 。 |
| Component (组件) | 纯数据载体。存储实体的属性(如坐标、血量),不包含任何业务逻辑 。 | Model/ModelView | 1. 严禁包含逻辑函数。 2. 若含数据字段,必须编写生命周期函数防止对象池复用错误 。 |
| System (系统) | 纯逻辑执行者。处理组件数据的计算与状态变更(如移动算法、碰撞检测)。 | Hotfix/HotfixView | 1. 必须是静态类或扩展方法,严禁包含数据字段。 2.严禁在 Model 层调用 Unity 引擎 API 。 |
ECS 实现价值:
- 低耦合:通过“数据在 Model,逻辑在 Hotfix"的物理隔离,避免了逻辑污染数据结构 。
- 热更新支持:逻辑代码位于
Hotfix程序集,修改游戏玩法只需替换 DLL,无需重启服务器或重打包客户端 。 - 性能优化:摒弃虚函数调用,使用静态扩展方法进行逻辑分发,减少 CPU 开销 。
2. 核心技术实现机制
ET 框架的技术底层围绕单线程异步模型、Scene 层级树及Actor 消息机制构建,确保高并发下的稳定性。
2.1 单线程异步纤程 (Fiber)
ET 服务器默认采用单线程事件循环,利用自定义的ETTask和 C#async/await语法模拟协程。
- 原理:当代码执行到 IO 操作(如数据库查询、网络收发)时,当前纤程挂起,线程立即去处理其他请求;IO 完成后恢复纤程继续执行 。
- 优势:实现了高并发且无线程锁开销,避免了多线程竞争导致的死锁与性能损耗 。
//示例:ET 框架中的异步逻辑处理 public static async Task ETTaskExample(this MoveComponent self) { // 1. 执行同步计算 Vector3 newPos = self.TargetPosition; //2. 遇到 IO 操作(如数据库读取),使用 await 挂起当前纤程,不阻塞主线程 var dbData = await Database.GetAsync("player_info"); // 3. IO 完成后自动恢复执行,继续处理逻辑 self.ApplyData(dbData); }2.2 Scene 层级树管理
ET 使用Scene作为内存管理的根节点,形成树状结构,不同端的 Scene 架构有所区别:
- 客户端:通常只有一个
ZoneScene,所有游戏对象挂载其下,对应单进程 。 - 服务端:采用多进程架构,每个进程是一个独立的
ZoneScene(如地图场景、战斗场景)。不同进程间通过Actor 消息通信,实现分布式部署与负载均衡 。
// 获取 Scene 示例 // 客户端:获取当前连接的服务器 ZoneScene 实例 var serverZone = self.ZoneScene(); // 服务端:获取当前进程 DomainScene 实例 var domain = self.DomainScene();2.3 网络通信与 Actor 模型
网络层基于ProtoBuf序列化,结合Session 会话与Actor 模型实现高效通信。
- 消息流程:消息定义 (.proto) -> 自动生成 C# 类 -> 接收解析 -> 分发至 Handler -> 业务处理 -> 响应返回 。
- Actor 模型:用于服务器内部进程间通信。每个 Entity 拥有唯一的 Actor ID,消息通过 ID 路由到目标进程的具体对象,无需关心物理位置 。
消息处理代码实现示例:
using ET; using System.Threading.Tasks; // 定义登录请求消息处理器 [MessageHandler(SceneType.Realm)] // 特性标记:指定由 Realm 服务器处理 public class C2R_LoginHandler : AMRpcHandler<C2R_Login, R2C_Login> { protected override async Task Run(Session session, C2R_Login request, Action<R2C_Login> response) { R2C_Login reply = new R2C_Login(); try { // 1. 业务逻辑验证 (伪代码) bool isValid = await AccountVerifier.VerifyAsync(request.account, request.password); if (!isValid) { reply.ErrorCode = 101; response(reply); return; } // 2. Actor 模型通信:向 Gate 服务器请求接入密钥 // 通过 Actor ID 发送内部消息,实现跨进程调用 var gateKeyInfo = await GetGateKeyFromRealm(request.account); reply.GateKey = gateKeyInfo.Key; reply.GateAddress = gateKeyInfo.Address; reply.ErrorCode = 0; } catch (System.Exception e) { reply.ErrorCode = 500; reply.message = e.Message; } // 3. 返回响应 response(reply); // 4. 关闭临时 Session (Realm 仅负责认证转发) session.Dispose(); } }3. 总结
ET 框架通过ECS 架构实现了数据与逻辑的物理分离,配合单线程异步纤程解决了高并发锁竞争问题,并利用Scene 层级树与Actor 模型构建了灵活的分布式服务器架构。这种设计使得开发者能够专注于业务逻辑(Hotfix 层),同时享受高性能与热更新带来的工程便利 。
参考来源
- 【ET框架】基础及实践难题解答
- 【高质量毕设开题】基于Android的室内装修案例展示与预算报价系统设计与实现(源码+报告)
- 工作中使用到的单词(软件开发)_第三版