欢迎转载,请注明作者【燕良@游戏开发】及原文地址:http://blog.csdn.net/neil3d/article/details/39580197

另外。欢迎大家来我的QQ群交流各种游戏引擎相关的技术:游戏引擎能吃吗(264656505)

话说,经过这段时间的学习和摸索。对于Unity3D的开发思路已经基本清晰了。

只有还剩下一个AssetBundle机制还没有搞透,这个涉及到前期项目的资源规划、资源管理代码的写法。以及自己主动更新机制的实现。

所以,还是想先把游戏逻辑的进一步分析押后,先来看一下《炉石传说》Asset管理。必须得说一下的是,眼下分析都是PC版的程序集。对于移动端不一定全然合适,且当做一个案例分析吧。

本文主要讲述《炉石传说》的AssetBundle的管理机制。它的机制比較简单清晰,中规中矩,中间的分析过程就不讲了,直接展现其架构设计和代码逻辑组织。

先从Asset管理相关的类讲起。

class Asset :资源信息描写叙述


Asset类,并无论理直接的资源对象,而是保存的一个Asset相关的信息。详细请看上图。
另外,它另一个“paths”变量,这是一个Dictionary。key是AssetFamily枚举。value是Assetbundle的路径和资源路径。

以下的AssetFamily一节详解。

enum AssetFamily - 资源分类


如上图所看到的:
  • 炉石依据资源的不同类型进行分别的AssetBundle打包,一类资源相应一个或者多个资源包。(一类资源分多个包的规则不得而知);
  • 有的资源包真的本地化单独打包,比如“fonts0.unity3d”==》“fontszhCN0.unity3d”;
  • 在程序中。资源包的分类相应枚举类型“AssetFamily”。
  • 资源包的详细路径信息。存储在Asset.paths,这是一个静态变量;在初始化时,手动填写必要的信息,类似这样:
        Dictionary<AssetFamily, AssetFamilyPathInfo> dictionary = new Dictionary<AssetFamily, AssetFamilyPathInfo>();
    AssetFamilyPathInfo info = new AssetFamilyPathInfo {
    format = "Data/Actors/{0}.unity3d",
    sourceDir = "Assets/Game/Actors"
    };
    info.exts = new string[] { "prefab" };
    dictionary.Add(AssetFamily.Actor, info);
  • 另外。另一个class AssetBundleInfo是记录了每种AssetBundle相应的主文件名称。以及包文件的个数、相应的对象类型等信息;详见下图:

class AssetLoader :资源载入


游戏执行时须要载入各种资源。基本上都是通过AssetLoader(也有个别情况适用了Resources.Load())。接下来我们就重点看一下AssetLoader的实现思路。


AssetLoader对上层提供资源对象载入接口。对于每种类型的资源都提供一组函数,比如LoadCardPrefab,LoadActor等等。对于对象载入完毕、载入进度等提供回调函数。这些函数仅仅是一些简单的包装。其内部都调用到LoadCachedGameObject()或LoadCachedObject()这两个核心函数。
从这两个函数的流程能够看到,资源载入使用到了Cache机制:
  • 首先从AssetCache中查找,假设找到了。则更新Cache项的时间戳。并调用回调;
  • 假设没有找到,则向AssetCache加入一个Request,然后启动Coroutine:CreateCachedAsset(),它的调用步骤是:
    • 调用AssetCache.StartLoading()。
    • 启动Coroutine:CreateCachedAsset_FromBundle<RequestType>():
      • 使用AssetLoader.GetBundleForAsset()找到资源所属的AssetBundle;
      • 调用AssetBundle.LoadAsync()来真正载入资源;
      • 在载入的过程中,依据处理的结果调用:AssetCache.CacheRequest的OnLoadFailed()、OnLoadSucceeded()、OnProgressUpdate()等函数;
    • 在AssetCache查找此资源。假设找到了,则载入成功,调用回调函数;

      调用AssetCache.StopLoading();

我们都知道在开发过程中,不能使用AssetBundle(每次启动都要打包。肯定收不了)。

怀疑它的Editor模式相关的代码是用预编译宏处理来实现的,所以未出如今公布出来的程序集其中。类似这样:

#if UNITY_EDITOR
Obj = Resources.LoadAssetAtPath(assetPath, typeof(T));
if (Obj == null)
Debug.LogError ("Asset not found at path: " + assetPath);
yield break;
#else

class AssetCache :资源的Cache机制

前面在AssetLoader一节我们已经讲到了AssetCache机制,这里再做一个具体的阐述。


前面我们已经讲到:
  • AssetCache中的资源项的时间戳,由AssetLoader在资源载入请求时维护;
  • AssetCache主要负责管理Cache数据,而真正的资源载入动作还是在AssetLoader中运行。
AssetCache的资源淘汰主要由外部的各个模块依据自己觉得须要的时机去调用,比如:
  • SceneMgr.ClearCachesAndFreeMemory()
  • LoadingScreen.ClearAssets()
  • SoundMgr.UnloadSoundBundle()
  • 等等
另外。程序启动时会自己主动更新资源包(在Login.OnAssetsVersion()中启动),主要是通过UpdateManager和Downloader两个类来处理。
OK,总结一下炉石的资源管理机制:
  • 对游戏资源依照类型分包。每一类资源包能够有多个。
  • 在游戏执行时使用Cache机制;
最后,还是顺便炫一下战绩:

《炉石传说》架构设计赏析(4):Asset管理的更多相关文章

  1. DotNET应用架构设计指南 安全 运行管理和通讯策略

    DotNET应用架构设计指南(第三章:安全 运行管理和通讯策略(13-16)) 安全 运行管理和通讯策略 组织策略定义的规则是支配应用程序如何安全,如何管理,不同的应用程序组件是如何和另一组件及外部服 ...

  2. 【tornado】系列项目(一)之基于领域驱动模型架构设计的京东用户管理后台

    本博文将一步步揭秘京东等大型网站的领域驱动模型,致力于让读者完全掌握这种网络架构中的“高富帅”. 一.预备知识: 1.接口: python中并没有类似java等其它语言中的接口类型,但是python中 ...

  3. 炉石传说 C# 设计文档(序)

    经过3个月的开发,有很多感触. 以前一直以为技术是开发成败的第一因素,现在发现,等到你代码写的时间够长,经验够丰富,什么功能都能随手完成,对于业务的分析能力变成了第一位. 炉石山寨版的BS版本用到的H ...

  4. 【Python之路】特别篇--基于领域驱动模型架构设计的京东用户管理后台

    一.预备知识: 1.接口: - URL形式 - 数据类型 (Python中不存在) a.类中的方法可以写任意个,想要对类中的方法进行约束就可以使用接口: b.定义一个接口,接口中定义一个方法f1: c ...

  5. 搭建rtmp直播流服务之3:java开发ffmpeg实现rtsp转rtmp并实现ffmpeg命令的接口化管理架构设计及代码实现

    上一篇文章简单介绍了java如何调用ffmpeg的命令:http://blog.csdn.net/eguid_1/article/details/51777716 上上一篇介绍了nginx-rtmp服 ...

  6. 架构设计之Spring-Session的分布式集群会话管理

    发表于 2017-04-24  |  160次围观   |   分类于 架构设计   |   暂无评论 前言 通常在web开发中,回话管理是很重要的一部分,用于存储与用户相关的一些数据.对于JAVA开 ...

  7. 架构设计 | 分布式系统调度,Zookeeper集群化管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.框架简介 1.基础简介 Zookeeper基于观察者模式设计的组件,主要应用于分布式系统架构中的,统一命名服务.统一配置管理.统一集群管理 ...

  8. 架构设计 | 接口幂等性原则,防重复提交Token管理

    本文源码:GitHub·点这里 || GitEE·点这里 一.幂等性概念 1.幂等简介 编程中一个幂等操作的特点是其任意多次执行所产生的影响均与一次执行的影响相同.就是说,一次和多次请求某一个资源会产 ...

  9. 架构设计 | 基于Seata中间件,微服务模式下事务管理

    源码地址:GitHub·点这里 || GitEE·点这里 一.Seata简介 1.Seata组件 Seata是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务.Seata将为用 ...

随机推荐

  1. javascript——js string 转 int 注意的问题——parseInt(转)

    <script>     var   str='1250' ;  alert( Number(str) );  //得到1250 alert(parseInt(str));  //得到12 ...

  2. css hack解决方案

    现在大家做项目的时候估计很多都已经不怎么考虑兼容问题,大多数的公司都已经舍弃ie7.8了,都是从ie9+开始,所以说不会有那么多的兼容问题需要去解决了,但是由于本人力求完美的工作习惯,做项目的时候还是 ...

  3. Windows——bat中的路径和工具栏运行bat的坑

    工具栏添加的批处理环境 编写一个简单的批处理文件 set testEnv = %cd% pause 这里第一句:设置当前文件夹路径为环境变量testEnv的值 这里第二句:暂停命令窗口 第一次我们直接 ...

  4. [Python3网络爬虫开发实战] 7.1-Selenium的使用

    Selenium是一个自动化测试工具,利用它可以驱动浏览器执行特定的动作,如点击.下拉等操作,同时还可以获取浏览器当前呈现的页面的源代码,做到可见即可爬.对于一些JavaScript动态渲染的页面来说 ...

  5. [Python3网络爬虫开发实战] 3.1.3-解析链接

    前面说过,urllib库里还提供了parse这个模块,它定义了处理URL的标准接口,例如实现URL各部分的抽取.合并以及链接转换.它支持如下协议的URL处理:file.ftp.gopher.hdl.h ...

  6. Linux内核0.11体系结构 ——《Linux内核完全注释》笔记打卡

    0 总体介绍 一个完整的操作系统主要由4部分组成:硬件.操作系统内核.操作系统服务和用户应用程序,如图0.1所示.操作系统内核程序主要用于对硬件资源的抽象和访问调度. 图0.1 操作系统组成部分 内核 ...

  7. Win2008 Server搭建流媒体服务(在线看电影)

    什么是流媒体服务呢. 所谓流媒体是指采用流式传输的方式在Internet播放的媒体格式, 与需要将整个视频文件全部下载之后才能观看的传统方式相比, 流媒体技术是通过将视频文件经过特殊的压缩方式分成一个 ...

  8. Python学习之单继承与多继承

    继承 面向对象编程语言的一个主要功能就是“继承”. 继承是指这样一种能力:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展. (1) 单继承:python同时支持类的继承 ...

  9. LLVM 概览

    下面是 LLVM 首页对 LLVM 介绍的中文翻译. LLVM 项目是一系列模块化.可重用和工具链技术的集合.不必在意它的名称,LLVM 和之前的虚拟机基本没什么关系了,然而也确实提供了对构建这些虚拟 ...

  10. IIS 注册.NET Framework 4.0 命令

    cmd执行以下命令 32位Windows:C:\Windows\Microsoft.NET\Framework\v4.0.30319\aspnet_regiis.exe -i 64位Windows:C ...