ET框架学习笔记 -基于Unity3D的ECS组件式编程

ET框架是一个十分强大的可以实现全热更的开源双端游戏框架,对于笔者这种人来说,简直就是量身打造,纯C#开发爽的不要不要的。就目前来看,ET框架已经相对稳定,猫大还在不断更新中,但是网上相关资料与技术博客还是很少,主要还是靠自己摸索,边用边琢磨;公司的游戏项目正是采用的ET框架开发,目前已经上线一个月;笔者使用ET的时间也不长,很多东西也是一知半解,难得闲下来,记下自己的理解,总结梳理一遍最近所学的知识,可能会有错误的理解,如果这篇文章有幸被你看到,欢迎留言指正。

ECS模式

ET是基于ECS概念设计的框架,ECS是Entity-Component-System的缩写,即实体-组件-系统;与传统的面向对象编程(Object Oriented Programming)相比,ECS模式遵循组合大于继承的原则,游戏中每一个物件都是一个实体Entity(ET的Entity实际上是继承自ComponentWithId,而ComponentWithId又是继承自Component;所以个人认为ET的每一个实体Entity实际上就是一个拥有自己的唯一ID的Component),如玩家,药水,装备,每个实体(Entity)又由一个或多个组件(Component)构成;组件(Component)代表实体的属性或者说是功能。比如说玩家需要移动,就给他添加一个移动组件,药水可以在背包中被拖拽,就给他添加一个拖拽组件,而游戏中的一个物体往往存在多个功能,物体与物体之间可能存在相同的功能,ECS模式把这些相同的功能单独剥离出来,与实体自由组合,实现代码的复用。而传统的设计思想往往都是把实体间的共性提炼出来作为一个基类,通过继这个承基类在每一种类型的实体中继续提炼出共性,一旦基类中增加或删除某个字段,可能要影响到所有派生类,影响到所有派生类相关的逻辑;如果需要对逻辑作出修改,要么重新实现,要么继承基类进行覆盖,有时候为了实现一个简单的功能却继承了一个十分庞大的类,导致许多不必要性能开销;这是ECS相对于面向对象的优势。

 

热更原理

C#代码会被编译成IL,IL解释成机器码的过程可以在运行之前进行也能在运行时进行,如果在运行时进行解释,那为什么不能跟lua一样热更?

Lua是使用C编写的脚本语言,它在运行时读入Lua编写的代码,在解释Lua字节码(Lua自己的指令)时不是翻译为机器码,而是用C写出来的Lua虚拟机,解释C代码。基于已经存在的某种语言的一种新的语言,这也是脚本语言和C#、C++这类语言的本质区别。

Unity3D提供了AssetBundle的资源打包方式,而Lua文件不需要编译,可以被当作文本资源直接打包进游戏的资源中,在游戏启动的过程中加载对应的脚本资源,解释执行转换为字节码,在Lua的虚拟机中执行,当前主流的xLua,uLua,ToLua,sLua都是以此实现热更的。而C#这种高级语言代码在编写后,先被各自的编译器编译成中间语言IL(CIL),等到需要真正执行的时候,这些IL会被加载到运行时库,也就是VM中,由VM动态的编译成汇编代码(JIT 即时编译,程序运行时创建并运行新代码)然后在执行。而IOS禁止了JIT编译,只能通过AOT在运行前提前编译成机器码,因此在手机端,没有对应的环境去翻译CIL,禁止了JIT以后,被当做资源热更的DLL就无法执行,所以IOS上C#不能热更。

ET的热更是基于C#热更方案ILRuntime实现的,而ILRuntime实现的基础,也是基于AssetBundle的资源热更新方式,将需要热更新的C#代码打包成DLL,在每次完成资源打包后,对应的DLL会被作为资源热更新出去。在Android平台可以不用任何第三方的热更方案,直接用C#反射Assembly.Load()执行DLL的方式实现热更。只是苹果禁止了C#的部分反射操作,禁止JIT编译,因此在IOS下不能使用反射动态载入DLL或者CS文件。而ET框架借助ILRuntime去读取C#的DLL得到IL汇编码,再使用IL2CPP将他们重新变回C++代码,然后再由各个平台的C++编译器直接编译成能执行的原生汇编代码,以此实现热更。

ET客户端部分

ET框架学习笔记 -基于Unity3D的ECS组件式编程_第1张图片

在第一次使用ET的时候,要根据熊猫GIT上的运行指南一步一步来,VS和Unity版本都不能错,然后可以看看初见和肉饼的视频学习。ET的客户端以Model层的Init脚本(凡是继承了MonoBehavoir类的脚本,都没办法进行热更)作为唯一入口,在Mode层调用Game.Hotfix.LoadHotfixAssembly(),利用AssetBundle加载热更代码的DLL,获取热更层程序集信息。

加载全局配置文件 Game.Scene.AddComponent
加载资源管理组件 Game.Scene.AddComponent
加载界面管理组件 Game.Scene.AddComponent
加载图集管理组件 Game.Scene.AddComponent
加载网络组件       Game.Scene.AddComponent
加载定时组件        Game.Scene.AddComponent
加载消息分发组件 Game.Scene.AddComponent
加载配置              Game.Scene.AddComponent

 

你可能感兴趣的:(ET框架学习笔记 -基于Unity3D的ECS组件式编程)