Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析

简介: Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析万物起源:Init.cs打开范例场景init.unity,可以发现其场景层级如下: 其中唯一重要的就是Global对象上挂在的init.

Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析

万物起源:Init.cs
打开范例场景init.unity,可以发现其场景层级如下:
其中唯一重要的就是Global对象上挂在的init.cs脚本,关于其基础代码分析,还是建议大家看初见的教程(ghithub有链接)
在这里只想重点分析大家一定会关心的一个问题:init.cs是如何加载初始界面的
init.cs是如何加载初始界面的:
上节课分析了,init.cs首先加载UILoading界面,其加载流程大致是这样的,先上序列图,稍后结合序列图贴代码分析:
Unity
Init
BundleHelper
EventSystem
LoadingBeginEvent_CreateLoadingUI
UILoadingFactory
StartAsync
DownloadBundle()
Run(EventIdType.LoadingBegin)
Run()
Create()
实例化UILoading预制体,并附加UILoadingComponent(更新并显示加载进度)
StartAsync
Unity
Init
BundleHelper
EventSystem
LoadingBeginEvent_CreateLoadingUI
UILoadingFactory
加载初始界面的几个步骤如下:
调用EventSystem.Run(EventIdType.LoadingBegin)引发LoadingBegin事件:
public static class BundleHelper
{

public static async ETTask DownloadBundle()
{
    if (Define.IsAsync)
    {
        try
        {
            using (BundleDownloaderComponent bundleDownloaderComponent = Game.Scene.AddComponent<BundleDownloaderComponent>())
            {
                await bundleDownloaderComponent.StartAsync();

                Debug.Log("EventIdType.LoadingBegin");
                Game.EventSystem.Run(EventIdType.LoadingBegin);
                
                await bundleDownloaderComponent.DownloadAsync();
            }
            
            Game.EventSystem.Run(EventIdType.LoadingFinish);
            
            Game.Scene.GetComponent<ResourcesComponent>().LoadOneBundle("StreamingAssets");
            ResourcesComponent.AssetBundleManifestObject = (AssetBundleManifest)Game.Scene.GetComponent<ResourcesComponent>().GetAsset("StreamingAssets", "AssetBundleManifest");
        }
        catch (Exception e)
        {
            Log.Error(e);
        }

    }
}

}
由于在unity编辑器环境下IsAsync标志被设为false(在VS环境下选中IsAsync成员,右键→速览定义可见),也即异步加载资源才可见loading画面,所以实际上不会看到loading画面!
第19行为等待异步加载完毕后引发LoadingFinish事件,其流程与LoadingBegin类似,请同学们自行分析!
实现LoadingBegin事件处理程序:

[Event(EventIdType.LoadingBegin)]
public class LoadingBeginEvent_CreateLoadingUI : AEvent
{

 public override void Run()
 {
     UI ui = UILoadingFactory.Create();
     Game.Scene.GetComponent<UIComponent>().Add(ui);
 }

}
在这里有需要注意学习定义事件类的方法: 1. 为一个类添加Event标志(参数填具体事件类型) 2. 从AEvent继承 3. 此时,ET就会自动将该类识别为一个事件处理类(通过反射机制),并在EventSystem.Run被调用时执行LoadingBeginEvent_CreateLoadingUI事件类的Run方法!

第六行代码UILoadingFactory.Create()负责创建UILoading界面,下面代码加了注释:

public static class UILoadingFactory
{

 public static UI Create()
 {
     try
     {
         // KV是Resources文件夹下存储的本地预制体资源,主要存储一些键值对数据
         // 从KV加载UIType.UILoading预制体,并实例化UI对象:
         GameObject bundleGameObject = ((GameObject)ResourcesHelper.Load("KV")).Get<GameObject>(UIType.UILoading);
         GameObject go = UnityEngine.Object.Instantiate(bundleGameObject);
         go.layer = LayerMask.NameToLayer(LayerNames.UI);

         // 创建UI这个Entity,并将上面创建的UI对象作为该Entity的图形表示
         UI ui = ComponentFactory.Create<UI, string, GameObject>(UIType.UILoading, go, false);

         // 添加UILoadingComponent,该组件负责更新loading进度并刷新显示
         ui.AddComponent<UILoadingComponent>();
         return ui;
     }
     catch (Exception e)
     {
         Log.Error(e);
         return null;
     }
 }

}
说明: - UI类是一个Entity类,Entity间接从Component类继承,但只有Entity类可以附加组件,Component类不行 - Entity和Component的关系实际就是设计模式中的Composite模式 - UI类可以复用,当你要创建一个UI时,在ET框架下只要: - 添加一个static的UI工厂类,并在其中定义一个static的Create方法,具体实现参照UILoadingFactory - 为该工厂添加一个新的UI组件(从Component类继承),并实现该组件的事件系统(见下文)

实现UILoadingComponent并实现该组件的事件系统:

UILoading组件
public class UILoadingComponent : Component
{

 public Text text;

}
UILoading事件系统:
[ObjectSystem]
public class UiLoadingComponentAwakeSystem : AwakeSystem
{

 public override void Awake(UILoadingComponent self)
 {
     self.text = self.GetParent<UI>().GameObject.Get<GameObject>("Text").GetComponent<Text>();
 }

}

[ObjectSystem]
public class UiLoadingComponentStartSystem : StartSystem
{

 public override void Start(UILoadingComponent self)
 {
     StartAsync(self).Coroutine();
 }

 public async ETVoid StartAsync(UILoadingComponent self)
 {
     TimerComponent timerComponent = Game.Scene.GetComponent<TimerComponent>();
     long instanceId = self.InstanceId;
     while (true)
     {
         await timerComponent.WaitAsync(1000);

         if (self.InstanceId != instanceId)
         {
             return;
         }

         BundleDownloaderComponent bundleDownloaderComponent = Game.Scene.GetComponent<BundleDownloaderComponent>();
         if (bundleDownloaderComponent == null)
         {
             continue;
         }
         self.text.text = $"{bundleDownloaderComponent.Progress}%";
     }
 }

}
事件类的定义: 1. 添加[ObjectSystem]标志 2. 继承自对应的XxxSystem类,并实现基类的虚方法 - 事件类与Unity中含义类似,请自行参阅源码学习

总结:
通过对UILoading的学习,我们已经接触了ET的一个完整的ECS对象:
E:Entity,对应UI类
C:Component,对应UILoadingComponent类
S:System, 对应UiLoadingComponentAwakeSystem和 UiLoadingComponentStartSystem类
版权申明:
本文原创首发于以下网站:
博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
优梦创客的官方博客:https://91make.top
优梦创客的游戏讲堂:https://91make.ke.qq.com
『优梦创客』的微信公众号:umaketop
您可以自由转载,但必须加入完整的版权声明!

相关文章
|
8月前
|
数据采集 监控 网络安全
VMware Cloud Foundation Operations for Networks 9.0.1.0 发布 - 云网络监控与分析
VMware Cloud Foundation Operations for Networks 9.0.1.0 发布 - 云网络监控与分析
484 3
VMware Cloud Foundation Operations for Networks 9.0.1.0 发布 - 云网络监控与分析
|
8月前
|
机器学习/深度学习 大数据 关系型数据库
基于python大数据的青少年网络使用情况分析及预测系统
本研究基于Python大数据技术,构建青少年网络行为分析系统,旨在破解现有防沉迷模式下用户画像模糊、预警滞后等难题。通过整合多平台亿级数据,运用机器学习实现精准行为预测与实时干预,推动数字治理向“数据驱动”转型,为家庭、学校及政府提供科学决策支持,助力青少年健康上网。
|
8月前
|
人机交互 开发工具 vr&ar
使用Unity引擎开发Rokid主机应用的模型交互操作
本文介绍如何使用Unity引擎结合Rokid OpenXR Plugin开发空间计算应用,实现射线交互、模型操作等功能。涵盖环境配置、Demo导入、UI搭建与脚本编写,助力开发者快速构建AR交互应用。
|
9月前
|
机器学习/深度学习 算法 PyTorch
【Pytorch框架搭建神经网络】基于DQN算法、优先级采样的DQN算法、DQN + 人工势场的避障控制研究(Python代码实现)
【Pytorch框架搭建神经网络】基于DQN算法、优先级采样的DQN算法、DQN + 人工势场的避障控制研究(Python代码实现)
261 1
|
9月前
|
监控 前端开发 安全
Netty 高性能网络编程框架技术详解与实践指南
本文档全面介绍 Netty 高性能网络编程框架的核心概念、架构设计和实践应用。作为 Java 领域最优秀的 NIO 框架之一,Netty 提供了异步事件驱动的网络应用程序框架,用于快速开发可维护的高性能协议服务器和客户端。本文将深入探讨其 Reactor 模型、ChannelPipeline、编解码器、内存管理等核心机制,帮助开发者构建高性能的网络应用系统。
630 0
|
9月前
Vite使用svg-企业级开发(支持本地svg和网络svg渲染)
本教程介绍如何在Vite项目中集成SVG图标插件。首先安装`vite-plugin-svg-icons`,配置插件指向SVG图标目录,并注册全局组件。接着创建SVG图标组件,支持内部图标与外部图片展示。通过简单配置,即可在页面中灵活使用各类SVG图标,提升开发效率。
486 0
|
9月前
|
机器学习/深度学习 算法 PyTorch
【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究(Matlab、Python实现)
【DQN实现避障控制】使用Pytorch框架搭建神经网络,基于DQN算法、优先级采样的DQN算法、DQN + 人工势场实现避障控制研究(Matlab、Python实现)
408 0
|
10月前
|
数据采集 存储 数据可视化
Python网络爬虫在环境保护中的应用:污染源监测数据抓取与分析
在环保领域,数据是决策基础,但分散在多个平台,获取困难。Python网络爬虫技术灵活高效,可自动化抓取空气质量、水质、污染源等数据,实现多平台整合、实时更新、结构化存储与异常预警。本文详解爬虫实战应用,涵盖技术选型、代码实现、反爬策略与数据分析,助力环保数据高效利用。
533 0
|
SQL 安全 网络安全
网络安全与信息安全:知识分享####
【10月更文挑战第21天】 随着数字化时代的快速发展,网络安全和信息安全已成为个人和企业不可忽视的关键问题。本文将探讨网络安全漏洞、加密技术以及安全意识的重要性,并提供一些实用的建议,帮助读者提高自身的网络安全防护能力。 ####
493 17
|
SQL 安全 网络安全
网络安全与信息安全:关于网络安全漏洞、加密技术、安全意识等方面的知识分享
随着互联网的普及,网络安全问题日益突出。本文将从网络安全漏洞、加密技术和安全意识三个方面进行探讨,旨在提高读者对网络安全的认识和防范能力。通过分析常见的网络安全漏洞,介绍加密技术的基本原理和应用,以及强调安全意识的重要性,帮助读者更好地保护自己的网络信息安全。
370 10

热门文章

最新文章