当前位置: 首页 > news >正文

【ET8框架入门】2.ET框架解析

菜单栏相关:ENABLE_DLL选项

ET->ChangeDefine->ADD_ENABLE_DLL/REMOVE_ENABLE_DLL

一般在开发阶段使用Editor时需要关闭ENABLE_DLL选项。该选项关闭时,修改脚本之后,会直接重新编译所有的代码,Editor在运行时会直接使用最新的程序集。如果ENABLE_DLL选项是开启的,框架启动后会加载之前生成的程序集文件(这个文件需要在ET->BuildTool界面生成),导致每次需要应用修改,都要重新生成程序集文件。

框架解析

框架入口解析

启动流程如下

入口文件为Init,之后调用CodeLoader对代码进行加载
如果不是EnableDll模式则直接加载程序集。否则通过AB加载文件,之后调用LoadHotfix函数
LoadHotfix会加载程序集,并且调用EventSystem,根据特性注册对应事件的监听。
之后调用ET.Entry的Start方法。
ET.Entry.Start 进行初始化之后,调用FiberManager.Instance.Create

调用FiberInit事件,推送对应的EntryEvent事件
推送EntryEvent3,EntryEvent3_InitClient接收后推送AppStartInitFinish
AppStartInitFinish_CreateLoginUI接收该事件后,创建UI场景


UI系统

UI界面的生成流程

ET是通过异步方式创建UI,如下方例子,调用UIHelper.Create方法,指定创建UI的场景,UI类型和对应的层级

        protected override async ETTask Run(Scene scene, EventType.AppStartInitFinish args){await UIHelper.Create(scene, UIType.UILogin, UILayer.Mid);}

调用scene挂载的UIComponent组件,处理Create事件

        public static async ETTask<UI> Create(Scene scene, string uiType, UILayer uiLayer){return await scene.GetComponent<UIComponent>().Create(uiType, uiLayer);}

之后会标记有对应UIEvent特性的类,处理该事件,开始加载资源并生成对应的GameObject

    [UIEvent(UIType.UILogin)]public class UILoginEvent: AUIEvent{public override async ETTask<UI> OnCreate(UIComponent uiComponent, UILayer uiLayer){await uiComponent.DomainScene().GetComponent<ResourcesLoaderComponent>().LoadAsync(UIType.UILogin.StringToAB());GameObject bundleGameObject = (GameObject) ResourcesComponent.Instance.GetAsset(UIType.UILogin.StringToAB(), UIType.UILogin);GameObject gameObject = UnityEngine.Object.Instantiate(bundleGameObject, UIEventComponent.Instance.GetLayer((int)uiLayer));UI ui = uiComponent.AddChild<UI, string, GameObject>(UIType.UILogin, gameObject);ui.AddComponent<UILoginComponent>();return ui;}public override void OnRemove(UIComponent uiComponent){ResourcesComponent.Instance.UnloadBundle(UIType.UILogin.StringToAB());}}

UI组件解析

以UILogin为例子,对应的Prefab实际上只挂载了ReferenceCollector,ReferenceCollector负责将结点进行绑定

生成该GameObject之后,调用AddComponent

    [UIEvent(UIType.UILogin)]public class UILoginEvent: AUIEvent{public override async ETTask<UI> OnCreate(UIComponent uiComponent, UILayer uiLayer){string assetsName = $"Assets/Bundles/UI/Demo/{UIType.UILogin}.prefab";GameObject bundleGameObject = await uiComponent.Scene().GetComponent<ResourcesLoaderComponent>().LoadAssetAsync<GameObject>(assetsName);GameObject gameObject = UnityEngine.Object.Instantiate(bundleGameObject, uiComponent.UIGlobalComponent.GetLayer((int)uiLayer));UI ui = uiComponent.AddChild<UI, string, GameObject>(UIType.UILogin, gameObject);ui.AddComponent<UILoginComponent>();return ui;}public override void OnRemove(UIComponent uiComponent){}}

其中UILoginComponent负责显示对应成员

[ComponentOf(typeof(UI))]
public class UILoginComponent: Entity, IAwake
{public GameObject account;public GameObject password;public GameObject loginBtn;
}

AddComponent之后,会调用对应的System,这里UILoginComponentSystem就是对应的System,在Awake阶段通过ReferenceCollector对UILoginComponent进行了绑定,以及实现了对应的UI逻辑

[ObjectSystem]
public class UILoginComponentAwakeSystem : AwakeSystem<UILoginComponent>
{protected override void Awake(UILoginComponent self){ReferenceCollector rc = self.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>();self.loginBtn = rc.Get<GameObject>("LoginBtn");self.loginBtn.GetComponent<Button>().onClick.AddListener(()=> { self.OnLogin(); });self.account = rc.Get<GameObject>("Account");self.password = rc.Get<GameObject>("Password");}
}

场景切换

关于ET的场景切换相关逻辑可以查看

UILobbyComponentSystem处理进入Map的操作,先是调用EnterMap异步函数,等待EnterMapHelper异步返回后删除界面

        //UILobbyComponentSystempublic static async ETTask EnterMap(this UILobbyComponent self){await EnterMapHelper.EnterMapAsync(self.ClientScene());await UIHelper.Remove(self.ClientScene(), UIType.UILobby);}

之后EnterMapHelper会向服务器发起进入Map的请求

        //EnterMapHelperpublic static async ETTask EnterMapAsync(Scene clientScene){try{G2C_EnterMap g2CEnterMap = await clientScene.GetComponent<SessionComponent>().Session.Call(new C2G_EnterMap()) as G2C_EnterMap;clientScene.GetComponent<PlayerComponent>().MyId = g2CEnterMap.MyId;// 等待场景切换完成await clientScene.GetComponent<ObjectWait>().Wait<Wait_SceneChangeFinish>();EventSystem.Instance.Publish(clientScene, new EventType.EnterMapFinish());}catch (Exception e){Log.Error(e);}       }


 

相关文章:

  • 34.用过JavaConfig方式的spring配置吗?它是如何替代xml的?
  • vue 中国省市区级联数据 三级联动
  • ASF-YOLO开源 | SSFF融合+TPE编码+CPAM注意力,精度提升!
  • Redis权限管理体系(一):客户端名及用户名
  • Javascript 前端分页——根据页面大小(pageSize)和总行数(total)计算总页面数(totalPage)
  • Java构建线程的方式
  • 基于ESP32的Blinker控制四路继电器连接RYG灯和白灯+蜂鸣器
  • vue3+vite4中使用svg,使用iconfont-svg图标
  • K8S(七)—污点、容忍
  • mysql的BIT数值类型
  • 微信小程序scroll-view的scroll-into-view和vanUI的tabs标签结合使用
  • 智能优化算法应用:基于共生生物算法3D无线传感器网络(WSN)覆盖优化 - 附代码
  • Nginx的stream配置
  • [足式机器人]Part2 Dr. CAN学习笔记-数学基础Ch0-7欧拉公式的证明
  • 如何在Facebook Business Manager进行企业认证
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 【391天】每日项目总结系列128(2018.03.03)
  • Angular4 模板式表单用法以及验证
  • co模块的前端实现
  • GDB 调试 Mysql 实战(三)优先队列排序算法中的行记录长度统计是怎么来的(上)...
  • gf框架之分页模块(五) - 自定义分页
  • gitlab-ci配置详解(一)
  • JavaScript的使用你知道几种?(上)
  • JavaScript工作原理(五):深入了解WebSockets,HTTP/2和SSE,以及如何选择
  • spring + angular 实现导出excel
  • Vue--数据传输
  • Yii源码解读-服务定位器(Service Locator)
  • 从零到一:用Phaser.js写意地开发小游戏(Chapter 3 - 加载游戏资源)
  • 规范化安全开发 KOA 手脚架
  • 你真的知道 == 和 equals 的区别吗?
  • 前端工程化(Gulp、Webpack)-webpack
  • 浅谈Kotlin实战篇之自定义View图片圆角简单应用(一)
  • 区块链分支循环
  • 使用Gradle第一次构建Java程序
  • 通过npm或yarn自动生成vue组件
  • 微信开源mars源码分析1—上层samples分析
  • 学习ES6 变量的解构赋值
  • 400多位云计算专家和开发者,加入了同一个组织 ...
  • Java性能优化之JVM GC(垃圾回收机制)
  • 阿里云服务器如何修改远程端口?
  • (zhuan) 一些RL的文献(及笔记)
  • (非本人原创)我们工作到底是为了什么?​——HP大中华区总裁孙振耀退休感言(r4笔记第60天)...
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (机器学习-深度学习快速入门)第一章第一节:Python环境和数据分析
  • (九十四)函数和二维数组
  • (十二)python网络爬虫(理论+实战)——实战:使用BeautfulSoup解析baidu热搜新闻数据
  • (一)Neo4j下载安装以及初次使用
  • (一)使用Mybatis实现在student数据库中插入一个学生信息
  • (译)2019年前端性能优化清单 — 下篇
  • (转)菜鸟学数据库(三)——存储过程
  • (转)拼包函数及网络封包的异常处理(含代码)
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • .NET CLR Hosting 简介