一、可寻址资源管理器模块设计
1.可寻址资源管理器作用
AddressableManager 可寻址资源管理器系统它能够帮助解决游戏开发中最重要的一些挑战:高效率和轻松的内容管理。在管理游戏资源时,往往很难维持好的标准,从而避免让项目变得杂乱无章。最主要的问题在于不同职责的资源管理系统之间的耦合。而且,项目中资源的存储,加载和载入后资源的使用方法都有紧密的联系。
假如,我们可能要在Resources文件夹存储某个精灵。这会让Unity在构建版本时,把精灵存到特定的存档文件中。由于精灵存在了这样的位置,我们必须通过Resources API来加载该精灵。项目变得混乱的速度比你想象的更快,一种方法的选择将造成项目长期的结果。一个好的系统会避免我们轻易犯下草率的错误,一个优秀的系统也会易于学习和使用。通过使用可寻址资源管理器,我们可以将资源管理问题分离。我们的目标是保持灵活性,同时让项目具有可维护性。
2.可寻址资源管理器优点有三
优点1:减少游戏的内存压力
在发布游戏时,大多数平台都会让开发者提供玩游戏所需的最低硬件配置要求,以便玩家在购买时参考。
原因很简单:要求的硬件配置越高,购买游戏的玩家会越少。而从另一个角度看,实现的内存管理越好,我们便可在游戏提供更多内容和乐趣。 可寻址资源管理器的第一个优点便是:高效的内存管理。
优点2:可以让开发者完全控制存储和加载游戏资源,从而有助于开发者添加和出售可下载内容(dlc)或者动态下载必须要的资源。
即使目前不考虑发布DLC内容或者无需动态下载资源,只要在项目中打包时设置成非母包资源,也可减小包体,可为上架Google海外市场做支持。
优点3:会减少在多个过程的等待时间
任何玩家都不喜欢等待,可寻址资源管理器系统会提供以下帮助:减少构建大小
游戏往往有很多内容,玩家喜欢体验内容,而开发者喜欢创作内容,并将把游戏内容提供给玩家。但这并不意味着,我们创作的每个资源都要包含在玩家安装的构建版本中。
实际上,我们要尽可能移除不必要的内容。玩家都希望尽快开始玩游戏。如果游戏需要1GB的数据流量,以及半小时的下载时间,玩家会对此感到不满。这样,玩家可能会更倾向于下载《Candy Crush》这类大小低于50MB的游戏。其中一种应对策略是:只在安装程序包含主菜单等运行游戏所需的资源,然后在后台下载剩余游戏内容,首先要下载的是游戏的关卡内容。这也会使开发期间的部署速度变得更快。我们将能够每天迭代更多次数,这个好处会在长期时间中累积效果。
3.UML静态视图设计
4.子模块一 热更新资源管理器模块(ResourceManager)
热更新资源管理器模块的主要作用是在游戏APP启动后,拉取CDN中的文件信息,
1.下载更新本地和CDN中有差异的文件;
2.下载更新CDN中新增文件;
3.下载本地没有的初始资源(母包资源);
4.删除CDN中已经失效的资源;
5.删除CDN的MD5和可写区的MD5不一致,CDN的MD5和只读区的MD5一致的资源。
5.子模块二 资源加载管理器模块(ResourceLoaderManager)
资源加载管理器是面向用户的类,资源加载完成后全部都会缓存进预制池中,节省下次加载速度对CPU性能进行优化。资源加载管理器可加载AssetBundle资源,Asset资源,分类资源。资源加载管理器已经实现基于AssetBundle的加载方式,基于Http的加载方式,加载过程中采用异步加载的方式,此方式对程序的平滑度较友好,但是难度稍大一些,使用回调的方式,加载器加载完成后通知上层,然后上层执行表现上的刷线。
6.依赖依赖与子模块
可寻址资源管理器是一个大模块,内部是众多的子模块拼装而成,可寻址资源管理器其实也是一个偏上层的模块,如果想要实现可寻址资源管理器模块,必须要先实现以下依赖模块和子模块 , 可寻址资源管理器模块比较庞大,后期框架搭建好之后会将代码工程放到国内的托管平台上(访问速度快,大家就不用翻墙了),方便大家学习。
HTTP网络模块:可寻址资源管理器中的作用是 访问CDN资源列表和动态下载资源
Http服务模块:https://blog.csdn.net/qq_33531923/article/details/128058782
断点续传下载器:https://blog.csdn.net/qq_33531923/article/details/128166379扫描二维码关注公众号,回复: 14550306 查看本文章
可寻址资源管理器子模块:真正做事情的模块
只读区资源管理器:https://blog.csdn.net/qq_33531923/article/details/128489546
可写区资源管理器:https://blog.csdn.net/qq_33531923/article/details/128489925
AssetBundle加载器:https://blog.csdn.net/qq_33531923/article/details/128537420
Asset加载器:https://blog.csdn.net/qq_33531923/article/details/128537420
任务管理器:https://blog.csdn.net/qq_33531923/article/details/128545543
资源加载器:https://blog.csdn.net/qq_33531923/article/details/128489446
主资源加载器:https://blog.csdn.net/qq_33531923/article/details/128545388
热更新资源管理器:
二、代码实现
可寻址资源管理器(AddressableManager)完整代码
public class AddressableManager : ManagerBase, IDisposable
{
//本地文件路径(开不开AB包,路径不一样)
//开assetbundle:dataPath
//不开assetBundle:可写区(App数据缓存区)
public string LocalFilePath;
//资源管理器
public ResourceManager ResManager
{
get;
private set;
}
//资源加载管理器
public ResourceLoaderManager ResLoaderManager
{
get;
private set;
}
public AddressableManager()
{
ResManager = new ResourceManager();
ResLoaderManager = new ResourceLoaderManager();
}
//可寻址管理器初始化
public override void Init()
{
#if DISABLE_ASSETBUNDLE //不是assetbundle模式,读取安装目录的只读区的文件
LocalFilePath = Application.dataPath;
#else //assetbundle模式,读取可写区
LocalFilePath = Application.persistentDataPath;
#endif
//资源管理器 和 资源加载管理器初始化
ResManager.Init();
ResLoaderManager.Init();
/*
* 这是所有异步操作单帧内所花费的最大时间。
* ThreadPriority.Low - 2ms 单帧停留2ms
* ThreadPriority.BelowNormal - 4ms 单帧停留4ms
* ThreadPriority.Normal - 10ms 单帧停留10ms
* ThreadPriority.High - 50ms 单帧停留50ms
* 停留的时间越长,理论上能加载的资源也就越多,加载速度越快。
* 但是对游戏整体的性能也就越低
*/
Application.backgroundLoadingPriority = ThreadPriority.High;
}
public void InitAssetInfo(BaseAction initAssetInfoComplete)
{
ResLoaderManager.InitAssetInfo(initAssetInfoComplete);
}
public void InitStreamingAssetsBundleInfo()
{
if (null != ResManager)
{
ResManager.InitStreamingAssetsBundleInfo();
}
}
public void OnUpdate()
{
//驱动ResouceLoaderManager更新
ResLoaderManager.OnUpdate();
}
//获取路径最后的名称
public string GetLastPathName(string pathName)
{
//没有/
if (pathName.IndexOf('/') == -1)
{
return pathName;
}
//截取最后一个'/' 往后的所有字符串
return pathName.Substring(pathName.LastIndexOf('/') + 1);
}
//获取场景的资源包路径(相对路径)
public string GetSceneAssetBundlePath(string sceneName)
{
return string.Format("download/scenes{0}.assetbundle", sceneName.ToLower());
}
public void Dispose()
{
ResManager.Dispose();
ResLoaderManager.Dispose();
}
}
引用:https://www.shuzhiduo.com/A/nAJv00j3dr/