经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » 游戏设计 » 查看文章
Unity进阶之ET网络游戏开发框架 03-Hotfix层启动
来源:cnblogs  作者:优梦创客  时间:2019/8/20 8:39:18  对本文有异议

版权申明:

  • 本文原创首发于以下网站:
  1. 博客园『优梦创客』的空间:https://www.cnblogs.com/raymondking123
  2. 优梦创客的官方博客:https://91make.top
  3. 优梦创客的游戏讲堂:https://91make.ke.qq.com
  4. 『优梦创客』的微信公众号:umaketop
  • 您可以自由转载,但必须加入完整的版权声明!

概要

  • 在init.cs中:
    • 首先,await到DownloadBundle完毕(即使是异步的)
    • 然后,Game.Hotfix.GotoHotfix()负责启动Hotfix层,进而启动UILogin画面
    • 本节就主要分析UILogin的启动流程,以及其事件处理

先上Hotfix入口代码:

  1. public void LoadHotfixAssembly()
  2. {
  3. Game.Scene.GetComponent<ResourcesComponent>().LoadBundle($"code.unity3d");
  4. GameObject code = (GameObject)Game.Scene.GetComponent<ResourcesComponent>().GetAsset("code.unity3d", "Code");
  5. byte[] assBytes = code.Get<TextAsset>("Hotfix.dll").bytes;
  6. byte[] pdbBytes = code.Get<TextAsset>("Hotfix.pdb").bytes;
  7. #if ILRuntime
  8. Log.Debug($"当前使用的是ILRuntime模式");
  9. // ...
  10. #else
  11. Log.Debug($"当前使用的是Mono模式");
  12. this.assembly = Assembly.Load(assBytes, pdbBytes);
  13. Type hotfixInit = this.assembly.GetType("ETHotfix.Init");
  14. this.start = new MonoStaticMethod(hotfixInit, "Start");
  15. this.hotfixTypes = this.assembly.GetTypes().ToList();
  16. #endif
  17. Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle($"code.unity3d");
  18. }
  19. public void GotoHotfix()
  20. {
  21. #if ILRuntime
  22. ILHelper.InitILRuntime(this.appDomain);
  23. #endif
  24. this.start.Run();
  25. }
  • 由于ILRT模式无法调试,所以开发阶段选择Mono模式,下面的分析也是以Mono方式为例的,这也是ET作者建议的工作流程(开发用Mono,发布用ILRT)
  • LoadHotfixAssembly:得到start方法
    • start方法实际就是ETHotfix命名空间下的Init类的Start方法
  • GotoHotfix:执行start方法

ETHotfix.Init.Start():

  1. namespace ETHotfix
  2. {
  3. public static class Init
  4. {
  5. public static void Start()
  6. {
  7. #if ILRuntime
  8. if (!Define.IsILRuntime)
  9. {
  10. Log.Error("Model层是mono模式, 但是Hotfix层是ILRuntime模式");
  11. }
  12. #else
  13. if (Define.IsILRuntime)
  14. {
  15. Log.Error("Model层是ILRuntime模式, Hotfix层是mono模式");
  16. }
  17. #endif
  18. try
  19. {
  20. // 注册热更层回调
  21. ETModel.Game.Hotfix.Update = () => { Update(); };
  22. ETModel.Game.Hotfix.LateUpdate = () => { LateUpdate(); };
  23. ETModel.Game.Hotfix.OnApplicationQuit = () => { OnApplicationQuit(); };
  24. Game.Scene.AddComponent<UIComponent>();
  25. Game.Scene.AddComponent<OpcodeTypeComponent>();
  26. Game.Scene.AddComponent<MessageDispatcherComponent>();
  27. // 加载热更配置
  28. ETModel.Game.Scene.GetComponent<ResourcesComponent>().LoadBundle("config.unity3d");
  29. Game.Scene.AddComponent<ConfigComponent>();
  30. ETModel.Game.Scene.GetComponent<ResourcesComponent>().UnloadBundle("config.unity3d");
  31. UnitConfig unitConfig = (UnitConfig)Game.Scene.GetComponent<ConfigComponent>().Get(typeof(UnitConfig), 1001);
  32. Log.Debug($"config {JsonHelper.ToJson(unitConfig)}");
  33. Game.EventSystem.Run(EventIdType.InitSceneStart);
  34. }
  35. catch (Exception e)
  36. {
  37. Log.Error(e);
  38. }
  39. }
  40. }
  41. }
  • 注意:第86行,和上一课的分析类似,也是在初始化阶段通过引发事件来创建UI界面,只不过这次的事件是InitSceneStart

InitSceneStart_CreateLoginUI.Run():

  1. namespace ETHotfix
  2. {
  3. [Event(EventIdType.InitSceneStart)]
  4. public class InitSceneStart_CreateLoginUI: AEvent
  5. {
  6. public override void Run()
  7. {
  8. UI ui = UILoginFactory.Create(); // 注意:这次是调用Hotfix层的UILoginFactory的Create工厂方法来创建UI实体,下面会重点分析
  9. Game.Scene.GetComponent<UIComponent>().Add(ui); // 注意:这次是添加Hotfix层的UIComponent组件,其代码与模型层类似,不再赘述
  10. }
  11. }
  12. }

UILoginFactory.Create():

```csharp
namespace ETHotfix
{
public static class UILoginFactory
{
public static UI Create()
{
try
{
ResourcesComponent resourcesComponent = ETModel.Game.Scene.GetComponent();
resourcesComponent.LoadBundle(UIType.UILogin.StringToAB());
GameObject bundleGameObject = (GameObject)resourcesComponent.GetAsset(UIType.UILogin.StringToAB(), UIType.UILogin);
GameObject gameObject = UnityEngine.Object.Instantiate(bundleGameObject);

  1. UI ui = ComponentFactory.Create<UI, string, GameObject>(UIType.UILogin, gameObject, false);
  2. ui.AddComponent<UILoginComponent>();
  3. return ui;
  4. }
  5. catch (Exception e)
  6. {
  7. Log.Error(e);
  8. return null;
  9. }
  10. }
  11. }

}```

  • 注意:
    • 这次加载的是从AB包加载UILogin预制体资源,而上节课是从Resources文件夹加载UILoading资源,不一样!
    • 虽然通过ComponentFactory.Create创建的Entity还是UI Entity,但该Entity添加的组件和上节课不一样,是“UILoginComponent”!

UILoginComponent事件处理:

  1. namespace ETHotfix
  2. {
  3. [ObjectSystem]
  4. public class UiLoginComponentSystem : AwakeSystem<UILoginComponent>
  5. {
  6. public override void Awake(UILoginComponent self)
  7. {
  8. self.Awake();
  9. }
  10. }
  11. public class UILoginComponent: Component
  12. {
  13. private GameObject account;
  14. private GameObject loginBtn;
  15. public void Awake()
  16. {
  17. ReferenceCollector rc = this.GetParent<UI>().GameObject.GetComponent<ReferenceCollector>();
  18. loginBtn = rc.Get<GameObject>("LoginBtn");
  19. loginBtn.GetComponent<Button>().onClick.Add(OnLogin);
  20. this.account = rc.Get<GameObject>("Account");
  21. }
  22. public void OnLogin()
  23. {
  24. LoginHelper.OnLoginAsync(this.account.GetComponent<InputField>().text).Coroutine();
  25. }
  26. }
  27. }
  • 事件处理在UILoginComponent.Awake方法中被注册
  • 在Entity.AddComponent时,AwakeSystem.Awake()->UILoginComponent.Awake方法链会被调用

原文链接:http://www.cnblogs.com/raymondking123/p/11369644.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号