Unity进阶之ET网络游戏开发框架 03-Hotfix层启动
版权申明:
- 本文原创首发于以下网站:
 
- 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
 - 优梦创客的官方博客:https://91make.top
 - 优梦创客的游戏讲堂:https://91make.ke.qq.com
 - 『优梦创客』的微信公众号:umaketop
 
- 您可以自由转载,但必须加入完整的版权声明!
 
概要
- 在init.cs中:
- 首先,await到DownloadBundle完毕(即使是异步的)
 - 然后,Game.Hotfix.GotoHotfix()负责启动Hotfix层,进而启动UILogin画面
 - 本节就主要分析UILogin的启动流程,以及其事件处理
 
 
先上Hotfix入口代码:
public void LoadHotfixAssembly()
{
	Game.Scene.GetComponent<ResourcesComponent>().LoadBundle($"code.unity3d");
	GameObject code = (GameObject)Game.Scene.GetComponent<ResourcesComponent>().GetAsset("code.unity3d", "Code");
	byte[] assBytes = code.Get<TextAsset>("Hotfix.dll").bytes;
	byte[] pdbBytes = code.Get<TextAsset>("Hotfix.pdb").bytes;
#if ILRuntime
	Log.Debug($"当前使用的是ILRuntime模式");
	// ...
#else
	Log.Debug($"当前使用的是Mono模式");
	this.assembly = Assembly.Load(assBytes, pdbBytes);
	Type hotfixInit = this.assembly.GetType("ETHotfix.Init");
	this.start = new MonoStaticMethod(hotfixInit, "Start");
	this.hotfixTypes = this.assembly.GetTypes().ToList();
#endif
	Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle($"code.unity3d");
}
public void GotoHotfix()
{
#if ILRuntime
	ILHelper.InitILRuntime(this.appDomain);
#endif
	this.start.Run();
}
- 由于ILRT模式无法调试,所以开发阶段选择Mono模式,下面的分析也是以Mono方式为例的,这也是ET作者建议的工作流程(开发用Mono,发布用ILRT)
 - LoadHotfixAssembly:得到start方法
- start方法实际就是ETHotfix命名空间下的Init类的Start方法
 
 - GotoHotfix:执行start方法
 
ETHotfix.Init.Start():
namespace ETHotfix
{
	public static class Init
	{
		public static void Start()
		{
#if ILRuntime
			if (!Define.IsILRuntime)
			{
				Log.Error("Model层是mono模式, 但是Hotfix层是ILRuntime模式");
			}
#else
			if (Define.IsILRuntime)
			{
				Log.Error("Model层是ILRuntime模式, Hotfix层是mono模式");
			}
#endif
			try
			{
				// 注册热更层回调
				ETModel.Game.Hotfix.Update = () => { Update(); };
				ETModel.Game.Hotfix.LateUpdate = () => { LateUpdate(); };
				ETModel.Game.Hotfix.OnApplicationQuit = () => { OnApplicationQuit(); };
				Game.Scene.AddComponent<UIComponent>();
				Game.Scene.AddComponent<OpcodeTypeComponent>();
				Game.Scene.AddComponent<MessageDispatcherComponent>();
				// 加载热更配置
				ETModel.Game.Scene.GetComponent<ResourcesComponent>().LoadBundle("config.unity3d");
				Game.Scene.AddComponent<ConfigComponent>();
				ETModel.Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle("config.unity3d");
				UnitConfig unitConfig = (UnitConfig)Game.Scene.GetComponent<ConfigComponent>().Get(typeof(UnitConfig), 1001);
				Log.Debug($"config {JsonHelper.ToJson(unitConfig)}");
				Game.EventSystem.Run(EventIdType.InitSceneStart);
			}
			catch (Exception e)
			{
				Log.Error(e);
			}
		}
    }
}
- 注意:第86行,和上一课的分析类似,也是在初始化阶段通过引发事件来创建UI界面,只不过这次的事件是InitSceneStart
 
InitSceneStart_CreateLoginUI.Run():
namespace ETHotfix
{
	[Event(EventIdType.InitSceneStart)]
	public class InitSceneStart_CreateLoginUI: AEvent
	{
		public override void Run()
		{
			UI ui = UILoginFactory.Create(); // 注意:这次是调用Hotfix层的UILoginFactory的Create工厂方法来创建UI实体,下面会重点分析
			Game.Scene.GetComponent<UIComponent>().Add(ui); // 注意:这次是添加Hotfix层的UIComponent组件,其代码与模型层类似,不再赘述
		}
	}
}
UILoginFactory.Create():
namespace ETHotfix
{
    public static class UILoginFactory
    {
        public static UI Create()
        {
	        try
	        {
				ResourcesComponent resourcesComponent = ETModel.Game.Scene.GetComponent<ResourcesComponent>();
				resourcesComponent.LoadBundle(UIType.UILogin.StringToAB());
				GameObject bundleGameObject = (GameObject)resourcesComponent.GetAsset(UIType.UILogin.StringToAB(), UIType.UILogin);
				GameObject gameObject = UnityEngine.Object.Instantiate(bundleGameObject);
		        UI ui = ComponentFactory.Create<UI, string, GameObject>(UIType.UILogin, gameObject, false);
				ui.AddComponent<UILoginComponent>();
				return ui;
	        }
	        catch (Exception e)
	        {
				Log.Error(e);
		        return null;
	        }
		}
    }
}```
- 注意:
	- 这次加载的是从AB包加载UILogin预制体资源,而上节课是从Resources文件夹加载UILoading资源,不一样!
	- 虽然通过ComponentFactory.Create创建的Entity还是UI Entity,但该Entity添加的组件和上节课不一样,是“UILoginComponent”!
# UILoginComponent事件处理:
```csharp
namespace ETHotfix
{
	[ObjectSystem]
	public class UiLoginComponentSystem : AwakeSystem<UILoginComponent>
	{
		public override void Awake(UILoginComponent self)
		{
			self.Awake();
		}
	}
	public class UILoginComponent: Component
	{
		private GameObject account;
		private GameObject loginBtn;
		public void Awake()
		{
			ReferenceCollector rc = this.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>();
			loginBtn = rc.Get<GameObject>("LoginBtn");
			loginBtn.GetComponent<Button>().onClick.Add(OnLogin);
			this.account = rc.Get<GameObject>("Account");
		}
		public void OnLogin()
		{
			LoginHelper.OnLoginAsync(this.account.GetComponent<InputField>().text).Coroutine();
		}
	}
}
- 事件处理在UILoginComponent.Awake方法中被注册
 - 在Entity.AddComponent时,AwakeSystem.Awake()->UILoginComponent.Awake方法链会被调用
 
Unity进阶之ET网络游戏开发框架 03-Hotfix层启动的更多相关文章
- Unity进阶之ET网络游戏开发框架 02-ET的客户端启动流程分析
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶之ET网络游戏开发框架 01-下载、运行
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶之ET网络游戏开发框架  04-资源打包
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶之ET网络游戏开发框架  05-搭建自己的第一个Scene
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶之ET网络游戏开发框架 08-深入登录成功消息
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶之ET网络游戏开发框架 06-游客登录
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶之ET网络游戏开发框架 07-修正游客登录的异步BUG
		
版权申明: 本文原创首发于以下网站: 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123 优梦创客的官方博客:https://91make.top ...
 - Unity进阶技巧 - 动态创建UGUI
		
前言 项目中有功能需要在代码中动态创建UGUI对象,但是在网上搜索了很久都没有找到类似的教程,最后终于在官方文档中找到了方法,趁着记忆犹新,写下动态创建UGUI的方法,供需要的朋友参考 你将学到什么? ...
 - Unity进阶----Lua语言知识点(2018/11/08)
		
国内开发: 敏捷开发: 集中精力加班堆出来第一个版本 基本没啥大的bug 国外开发: 1).需求分析: 2).讨论 3).分模块 4).框架 5).画UML图(类图class function)(e- ...
 
随机推荐
- Bzoj 3165 [Heoi2013]Segment题解
			
3165: [Heoi2013]Segment Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 668 Solved: 276[Submit][Sta ...
 - C++ 编程技巧锦集(一)
			
C++刷题精髓在STL编程,还有一些函数.下面我就总结一下本人在刷题过程中,每逢遇见总要百度的内容………………(大概率因为本人刷题太少了) 1. map map<string, int> ...
 - 【题解】埃及分数-C++
			
Description 在古埃及,人们使用单位分数的和(形如1/a的, a是自然数)表示一切有理数. 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的. 对于一个分数a/ ...
 - BAT的人都是怎么学习的
			
不知道你发现没,在技术领域走在前列的人,基本都符合一个条件:保持对新技术的敏感度,还能定期更新自己的技能储备. 要做到这一点,最高效的办法就是直接跟 BAT 等一线大厂取经.说白了,平台足够大,就有更 ...
 - golang http json http://www.alexedwards.net/blog/golang-response-snippets
			
http://www.alexedwards.net/blog/golang-response-snippets https://gist.github.com/andreagrandi/97263a ...
 - 个人永久性免费-Excel催化剂功能第69波-专业图表库新增图表-刘万祥老师中国地图
			
Excel催化剂的[专业图表库],仅提供一个工具的输出,让用户可以在制作专业图表过程中更低的门槛,更快速的完成所想要实现的图表.具体参考:第69波-打造最专业易用的商务图表库https://www.j ...
 - 个人永久性免费-Excel催化剂功能第62波-单元格区域内数据加解密处理,最有效地保护数据方式
			
Excel的数据保护能力有限,诸如之前提及过的工作表保护.工作薄保护等,都是十分微弱的保护措施,而对于强保护的工作薄打开密码来说,它像是个总开关一样,要么全不能看,要么就全看到.有这样的场景需求,一份 ...
 - 个人永久性免费-Excel催化剂功能第57波-一键生成完全组合的笛卡尔积结果表
			
在数据库的多表查询中,通常会有各种连接关系,同样地在Excel环境中,也有很大的场景需要用到类似数据库的多表查询,如经典的VLOOKUP就是其中一种类似LEFT JOIN查询的查询效果.在很多时候需要 ...
 - AQS初体验
			
AQS初体验 AQS是AbstractQueuedSynchronizer的简称.AQS提供了一种实现阻塞锁和一系列依赖FIFO等待队列的同步器的框架.所谓框架,AQS使用了模板方法的设计模式,为我们 ...
 - 关于ArcGIS api for JavaScript的一些内容
			
2018-3-19 ArcGIS api for JavaScript 在3.4之后就已经抛弃了过时的写法,采用了AMD的写法,AMD规范即异步模块加载机制,这种规范让JS就像其它面向对象语言(比如J ...