Version: 1.3
语言 : 中文
性能优化指引
Auto Streaming用法

微信资源缓存

微信小游戏切断了JS文件系统和IndexDB的同步,以避免大量文件同步带来的卡顿问题。因此所有通过C# 文件IO保存的文件只会在内存中存在,而不会同步到持久化存储中。在游戏退出后,内存中的文件都会被释放。 微信提供了两种方式来持久化存储文件:

  1. 通过微信SDK提供的文件接口来存储文件

  2. 通过微信的下载缓存来避免重复下载

使用微信下载缓存时,微信小游戏在下载文件过程中,底层会自动匹配下载url中是否包含小游戏配置文件“Bundle Path Identifier”属性中的字段来决定是否缓存下载结果。由于缓存在小游戏框架底层实现,对引擎不可见,因此在游戏内每次都会触发下载请求。已缓存的url再次被请求时,将直接从缓存中读取,表现为下载时间更短。 具体缓存规则请参考微信官方文档 小游戏资源缓存

为了在使用微信下载缓存,避免AB文件的重复下载的同时,依旧支持游戏版本变动,即同一AB文件内资源随版本的变动。 打包AB时,需要在AB名称中附带hash,以便于微信管理下载缓存:

  1. 如果用代码打包AB,请添加BuildAssetBundleOptions.AppendHashToAssetBundleName选项

  2. 如果使用AssetBundleBrowser package打包AB,请按下图勾选

以使用Auto Streaming和UOS CDN为例。 AB打包完成后,需要手动将所有AB移动到引擎默认的目录CustomCloudAssets/CustomAB, 或其他自定义的目录(需要在微信打包页面自行填写Bundle Path Identififier使缓存生效,CustomAB已自动填写)。

C#代码中下载AB的URl根路径为: AutoStreaming.CustomCloudAssetsRoot+ {自定义子目录} + {带Hash的AB文件名}

由于AssetBundleManifest对应的AB(下图WebGL文件)文件名不带hash,不能放入微信缓存目录(CustomCloudAssets/CustomAB)中。否则后续游戏版本更新后, AssetBundleManifest却始终从缓存中获取,导致AB无法更新。

使用BuildAssetBundleOptions.AppendHashToAssetBundleName后,AB文件名称会随打包资源变化而变化,因此加载AB代码需要做相应的修改,从AssetBundleManifest中动态获取AB的名称。

加载远程AssetBundle示例:

//示例AB名称: bundle_cda40198af392ffe0419808051b8ac08

//生成字典 abName -> abNameWithHash
private Dictionary<string,string> GetABNamesWithHash(AssetBundleManifest abm) 
{
    var hashNames = abm.GetAllAssetBundles();
    Dictionary<string, string> ABNamesDict = 
        new Dictionary<string, string>();
    foreach (var hashName in hashNames)
    {
        //需要注意AB后缀名,默认 .unity3d
        var abName = Regex.Match(hashName,
        "_[0-9a-f]{32}.unity3d$").Success 
        ? hashName.Substring(0,hashName.Length - 33)
        : hashName;
        ABNamesDict.Add(abName, hashName);
    }
    return ABNamesDict;
}

IEnumerator LoadABAsync(string abName)
{
    //加载manifest
    var uwr = UnityWebRequestAssetBundle.GetAssetBundle(AutoStreaming.CustomCloudAssetsRoot + "WebGL");
    yield return uwr.SendWebRequest();
    if (uwr.result != UnityWebRequest.Result.Success) 
    {                 
        Debug.Log(uwr.error);
        yield break;             
    } 
    //获取映射字典
    AssetBundle manifestbundle = DownloadHandlerAssetBundle.GetContent(uwr);
    AssetBundleManifest  abm =  manifestbundle?.LoadAsset<AssetBundleManifest>("AssetBundleManifest");
    var hashNames = GetABNamesWithHash(abm);
    //获取ab带hash的完整文件名
    var abNameWithHash = hashNames[abName];

    //ab在服务器上的地址
    string abUrl = AutoStreaming.CustomCloudAssetsRoot + "CustomAB/" + abNmaeWithHash;
    //下载并加载AB
    UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(abUrl);
    yield return request.SendWebRequest();

    if(!request.isHttpError)
    {
        //成功下载并加载,加载资源
        ...
    }
}
性能优化指引
Auto Streaming用法