今天我们主要分析一下炉石这款游戏中一共有哪些Scene,他们各自负责什么,以及它内部的逻辑、UI的处理方式。

在正式开始之前,我来对前文中提到的Scene切换再做一些补充分析。前文中我们看到SceneMgr是调用了“Application.LoadLevelAdditiveAsync(this.sceneName);”,那内存中的东西岂不是越搞越多吗?我们再仔细看一下SceneMgr:SwitchMode()函数,它是一个Coroutine,他主要进行了下面这几个步骤的操作:

1.调用当前Scene的Scene:PreUnload()函数;

发送FireScenePreUnloadEvent事件;
等待直到Unload过程走完(通过检测LoadingScreen的阶段);

2.调用Scene:Unload()函数;

发送FireScenePreUnloadEvent事件;
调用成员函数PostUnloadCleanup()函数,它调用了两个关键的函数:

  • 首先是成员函数:DestroyAllObjectsOnModeSwitch(),这个函数查找到所有的GameObject(Object.FindObjectsOfType(typeof(GameObject))),然后进行了筛选(通过成员函数ShouldDestroyOnModeSwitch),除了一些全局对象之外(主要是SceneMgr、PegUI、Box、DefLoader),全都删除了(通过调用Object.DestroyImmediate())。
  • 然后调用了:Resources.UnloadUnusedAssets();

3.然后是调用前文提到过的成员函数:LoadModeFromModeSwitch(),进行了LoadLevelAdditiveAsync()操作;

综上所述,炉石的Scene切换主要是包含两步:1删除所有非全局对象,卸载未引用的Asset;2加载新的Scene。(我倒是想到另外一个土鳖一点的替代方案:创建一个完全空的scene,调用LoadLevel加载它,那么所有没有设置"DontDestroyOnLoad"的对象就都被删除了。)

除了前文提到的Login,我们可以看到Scene还有很多派生类,详见下图:

这是我猜测的这些类和游戏内容的对应关系,卖二手游戏平台没有太仔细分析,可能有些对应是错误的:

下面我们就挑选一个简单的Scene来分析一下它的内部运作机制,我们来看一下AdventureScene吧。Adventure相关的Class很多,我们只做一个粗略的分析,只涉及到下面这几个类和接口:

首先我推测,在Hub屏幕中点击中间的【Solo Adventure】(冒险模式)按钮之后,通过我们前文分析的LoadScene流程,加载了一个冒险模式相关的Scene。它里面有一个GameObject绑定了“AdventureScene”这个脚本,我们可以看到AdventureScene:Awake()方法中主要是注册了很多事件的回调。

我们可以看到有一个“AdventrueSubScenes”枚举,它基本上对应了下图中的按钮:

  1. <font color="#000000">public enum AdventureSubScenes
  2. {
  3. Chooser,
  4. Practice,
  5. MissionDeckPicker,
  6. NormalHeroic,
  7. ClassChallenge
  8. }</font>

复制代码

接下来还有一个"AdventureSubScene"是处理子场景对应的一些逻辑的。

我们看到有“AdventureChooserTray”这个类:

1.我推测这个类就是用来处理上面这个游戏画面的UI交互操作的;

2.这个类在Awake时,通过调用“CreateAdventureChooserButton()”方法创建了上图中的上部分那几个冒险游戏内容模式相关的按钮;

3.这些按钮都绑定了事件回调:AdventureChooserTray.ButtonModeSelected();当这些按钮被点击时,主要是调用:

  • AdventureConfig:SetSelectedAdventureMode(),此函数修改内部数据之后触发事件:FireSelectedModeChangeEvent()
  • AdventureChooserTray通过OnSelectedModeChange()响应此事件,这也就是点击上面那几个按钮之后要做的一些处理:包括更新左侧的画面、设置Choose按钮状态等等;
  • 其中调用了PlayMakerFSM,主要是向其发送事件“Burst”;通过这里,我们可以确定炉石使用了PlayerMaker插件。
  • AdventureScene也通过OnSelectedModeChanged()相应了此事件;

4.它里面还有一个“PlayButton m_ChooseButton”成员变量,并把为它添加了EventListener,用来调用ChangeSubScene()方法。这就和游戏实际的操作对应上来:在上面选择模式,然后点击下面的【Choose】按钮,就进行到下一步的选择了。

5.AdventureChooserTray:ChangeSubScene()通过Coroutine的方式调用了AdventureConfig:ChangeSubSceneToSelectedAdventure(),然后调用了AdventureConfig:ChangeSubScene();它主要触发两个事件:

  • FireSubSceneChangeEvent:AdventureScene通过OnSubSceneChange()函数响应它,主要是调用AdventureScene:LoadSubScene(),内部主要是调用AssetLoader.LoadUIScreen();
  • FireAdventureModeChangeEvent:AdventureScene通过OnAdventureModeChanged()响应它。

通过上面的分析,我们大致了解了上面这个游戏截图中的操作实现逻辑。

这次的分析算是一次热身,接下来重点分析有两个方面:

  • 游戏逻辑的组织,特别是技能的数据、逻辑组织;这可能需要经过多次尝试,慢慢接近;
  • 游戏的Asset资源管理、加载机制;

OK,今天的分析就到这里,欢迎大家拍砖。后续分析敬请期待!

顺便来秀一下我的鱼人部队,别看这些1点学的小东西,加在一起还蛮欢乐的!

《炉石传说》架构设计赏析(2):Scene管理相关推荐

  1. 微服务架构案例(02):业务架构设计,系统分层管理

    本文源码:GitHub·点这里 || GitEE·点这里 更新进度(共6节): 01:项目技术选型简介,架构图解说明 02:业务架构设计,系统分层管理 一.业务架构设计 1.基础概念 服务的架构设计决 ...

  2. 卫向军 | 从正交分解架构设计到矩阵式团队管理

    大家好,俗话说,早起的鸟儿有虫吃,非常高兴在新年之初与大家做一场矩阵式团队管理的交流分享. 今天的分享主题: <从正交分解架构设计到矩阵式团队管理> 带团队就是管人.管事.管钱.管心,合理 ...

  3. 《炉石传说》架构设计赏析(4):Asset管理

    话说,经过这段时间的学习和摸索,对于Unity3D的开发思路已经基本清晰了.唯独还剩下一个AssetBundle机制还没有搞透,这个涉及到前期项目的资源规划.资源管理代码的写法,以及自动更新机制的实现 ...

  4. 《炉石传说》架构设计赏析(1):游戏启动流程

    今年的Unity Awards两项大奖颁给了暴雪的<炉石传说>,这真是对Unity一个再好不过的宣传了--你看,暴雪都开始用Unity了.大家都知道,目前Unity发布的游戏大多都没有对程 ...

  5. 《炉石传说》架构设计赏析(6):卡牌 技能数据的运行时组织

    前一篇文章我们看到了<炉石传说>的核心卡牌数据的存储,今天我们继续探索卡牌&技能. 主要的类 通过之前的分析,卡牌&技能涉及到几个类体系:Entity,Actor,Card ...

  6. c语言炉石传说算法设计,CCF-CSP题解 201609-3 炉石传说

    模拟. 注意随从的编号在\(summon\)和\(attack\)随从死亡时都可能改变. #include using namespace std; struct tNode { int attack ...

  7. c语言炉石传说算法设计,FZU Problem 2232 炉石传说(匈牙利算法)

     Problem Description GG学长虽然并不打炉石传说,但是由于题面需要他便学会了打炉石传说.但是传统的炉石传说对于刚入门的GG学长来说有点复杂,所以他决定自己开发一个简化版的炉石传说. ...

  8. c语言炉石传说算法设计,炉石传说:下棋吃鸡还扣分?设计师:现在已经改回去了...

    原标题:炉石传说:下棋吃鸡还扣分?设计师:现在已经改回去了 随着16.0补丁的上线,很多酒馆战棋的高分玩家发现了一件非常反常的事情.那就是补丁更新之后,赢一局不仅不加分而且会扣分(前四名),甚至于吃鸡 ...

  9. 《炉石传说》架构设计赏析(3):Gameplay初探

    经过前面的分析,我们已经找到了两个关键的类Gameplay和GameState(当然还有我最感兴趣的Spell和SpellController,这两个还要在后面分析). 首先我们看一下Gameplay ...

最新文章

  1. Lambda表达式关于like问题(未解决)
  2. 几个常用的Linux监控脚本
  3. c# npoi 2.5版本设置字体加粗_巨巨巨巨推荐:SCI翻译神器,大版本更新来了
  4. Taro+react开发(80):状态改变的构造函数
  5. 与变异风险词赛跑 阿里探索AI治理网络风险
  6. Simulink之交流调压电路
  7. 取石子游戏(信息学奥赛一本通-T1218)
  8. 整数分区(求将整数拆分成任意个数正整数的方法个数)codewars 爆炸求和
  9. JSP设置IE版本兼容
  10. 搜狗推送接口-搜狗推送口子
  11. 那些悄悄变厉害的人,都在偷偷对自己下狠手
  12. 快速选择(QuickSelect)的平均时间复杂度分析
  13. H5手机浏览器唤起微信实现分享
  14. verilog之分频大全
  15. 服务器gosht引导盘,带RAID服务器能GHOST备份吗?
  16. Android基于网络的VoIP电话的实现linphone
  17. SourceTree使用教程图文详解
  18. 解决Error: Could not detect Mac OS X Version from sw_vers output: '10.14.3'
  19. 《数据密集型应用系统设计》读书笔记
  20. 2020年你应该关注这50款前端热门工具,JavaScript插件篇(一)

热门文章

  1. 哪个小姐姐是假的?Yann LeCun说合成人脸并不难分辨
  2. python类与对象示意图_2020Python作业——类与对象,
  3. mysql 执行计划不对_关于mysql主从查询执行计划不一致问题的分析
  4. prometheus变量_Prometheus 数据可视化
  5. 计算机控制系统从本质上看,计算机控制系统测试题.doc
  6. lesson3-字符串及其常用操作
  7. 钉钉小程序数据传递——子传父,父传子
  8. python工程结构
  9. LVS负载均衡下session共享的实现方式-持久化连接
  10. 点击文字,把input type=radio也选中