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


    欢迎转载,请注明作者【燕良@游戏开发】及原文地址: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机制;
    最后,还是顺便炫一下战绩:

  • 相关阅读:
    swift 自学小计
    修改非空表字段类型Oracle
    DBNull.value
    修改SqlServer字段长度
    未在本地计算机上注册“Microsoft.Ace.OleDB.12.0”
    引用dll文件要复制到本地
    oracle与SqlServer连接串服务器地址
    生成几乎永不重复的串
    安装SqlServer2008后vs中dev控件消失
    Ios项目添加Pods
  • 原文地址:https://www.cnblogs.com/wzjhoutai/p/7140818.html
Copyright © 2020-2023  润新知