【ET8】2.ET8入门-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类型和对应的层级

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

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

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

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

cs 复制代码
    [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

cs 复制代码
    [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负责显示对应成员

cs 复制代码
[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逻辑

cs 复制代码
[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异步返回后删除界面

cs 复制代码
        //UILobbyComponentSystem
        public static async ETTask EnterMap(this UILobbyComponent self)
        {
            await EnterMapHelper.EnterMapAsync(self.ClientScene());
            await UIHelper.Remove(self.ClientScene(), UIType.UILobby);
        }

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

cs 复制代码
        //EnterMapHelper
        public 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);
            }       
        }
相关推荐
异次元的归来10 小时前
Unity DOTS中的share component
unity·游戏引擎
向宇it14 小时前
【从零开始入门unity游戏开发之——C#篇25】C#面向对象动态多态——virtual、override 和 base 关键字、抽象类和抽象方法
java·开发语言·unity·c#·游戏引擎
_oP_i15 小时前
unity webgl部署到iis报错
unity
Go_Accepted15 小时前
Unity全局雾效
unity
向宇it15 小时前
【从零开始入门unity游戏开发之——C#篇24】C#面向对象继承——万物之父(object)、装箱和拆箱、sealed 密封类
java·开发语言·unity·c#·游戏引擎
每日出拳老爷子18 小时前
【图形渲染】【Unity Shader】【Nvidia CG】有用的参考资料链接
unity·游戏引擎·图形渲染
北海651619 小时前
Dots 常用操作
unity
YY-nb1 天前
Unity Apple Vision Pro 开发教程:物体识别跟踪
unity·游戏引擎·apple vision pro
Cool-浩1 天前
Unity 开发Apple Vision Pro物体识别追踪ObjectTracking
unity·ar·apple vision pro·mr·物体识别·vision pro教程·objecttracking
向宇it2 天前
【从零开始入门unity游戏开发之——C#篇23】C#面向对象继承——`as`类型转化和`is`类型检查、向上转型和向下转型、里氏替换原则(LSP)
java·开发语言·unity·c#·游戏引擎·里氏替换原则