从 AssetBundle 获取 Caching.IsVersionCached 函数的 Hash128

Get Hash128 from AssetBundle for the Caching.IsVersionCached function

我想知道 AssetBundle 已经在缓存中了。这通常使用 Caching.IsVersionCached 函数来完成。

Unity 2017.1.

不再支持 Caching.IsVersionCached(string url, int version) 函数重载

Unity 2017.3 建议我使用 Caching.IsVersionCached(string url, Hash128 hash) 重载。

我不知道Hash128是什么以及如何获取和使用它。 Hash128 用于什么,如何从 AssetBundle 中获取它?


感谢您的回答。

但我无法解决我的问题。

这是我的代码

for (int i = 0; i < assetInfoList.Count; i++) {

while (!Caching.ready)
    yield return null;


string url = GetUrl(assetInfoList[i].assetbundle_name);
string keyName = url + assetInfoList[i].version_no.ToString(); 

using (UnityWebRequest request = UnityWebRequest.GetAssetBundle(url,(uint)assetInfoList[i].version_no, 0))
{
    if (Caching.IsVersionCached(url, assetInfoList[i].version_no) == true)
        continue;

    if (i == 0)
    {
        string wifiConnectRecommend = Message.Ins.WIFI_ONLY;
        PopUpManager.Instance.PopUp_YesORNoForAssetBundle(wifiConnectRecommend.ToString(), ClickWifi, availableBytes, totalBytes);

        while (!SceneManager.Ins.isWifiUseConfirm)
            yield return null;

    }
    request.SendWebRequest();                

    while (request.isDone == false)
    {
        progressbar.value = request.downloadProgress;
        currentCount.text = countString + " (" + (request.downloadProgress * 100).ToString("N2") + "%)";
        yield return null;
    }

    if (request.error != null)
    {
        Debug.Log("www.error");
    }
    else
    {
        AssetBundleRef abRef = new AssetBundleRef(url, assetInfoList[i].version_no);
        abRef.assetBundle = DownloadHandlerAssetBundle.GetContent(request);

        dictAssetBundleRefs.Add(keyName, abRef);
    }
}

} 我的目的是当 assetbundle 已经在缓存中时,继续并需要下载,设置为 PopUp_YesORNoForAssetBundle.

检查assetbundle下载或版本检查时需要hash128。

但在您的解释中,hash128 仅在 assetbundle 上次加载或保存清单文件到资源文件夹后才获取。

我想知道如何检查 assetbunle 是否在缓存中。

如果你提出方法,我真的很感谢你。

but I don't know what is hash128

Hash128表示AssetBundle文件的哈希值,方便下载时比较AssetBundle文件的版本。

I can't find how to use hash128

文档中没有关于如何执行此操作的示例。以下是三种种获得Hash128的方法。使用哪一个取决于 AssetBundle 所在的位置以及是否要下载它来检查 Hash128 。在您的情况下,#1 可能是您要查找的内容。

1在 AssetBundle 构建期间从编辑器获取 Hash128 然后保存到资源文件夹:

使用 BuildPipeline.BuildAssetBundles 函数构建 AssetBundle 时,此函数 returns AssetBundleManifest。您可以使用AssetBundleManifest.GetAssetBundleHash函数获得Hash128。使用 Hash128.ToString()Hash128 转换为字符串,然后将其保存到 Resources 文件夹,以便 您可以在 运行 期间访问它-时间.

Editor 构建脚本示例,它将构建 AssetBundle 并将 Hash128 保存到资源文件夹:

[MenuItem("Assets/Build AssetBundle")]
static void ExportResource()
{
    string folderName = "AssetBundles";
    string filePath = Path.Combine(Application.streamingAssetsPath, folderName);

    AssetBundleManifest assetMf = BuildPipeline.BuildAssetBundles(filePath, BuildAssetBundleOptions.None, BuildTarget.StandaloneWindows64);

    //Get Hash128 from the AssetBundleManifest
    Hash128 hash128 = assetMf.GetAssetBundleHash("AssetBundles");

    //Get the Hash128 as string
    string data = hash128.ToString();
    string path = "Assets/Resources/AssetInfo/AssetBundleInfo.txt";

    //Save the Hash128 to the Resources folder
    using (FileStream fileStream = new FileStream(path, FileMode.Create))
    {
        using (StreamWriter writer = new StreamWriter(fileStream))
        {
            writer.Write(data);
        }
    }
    UnityEditor.AssetDatabase.Refresh();
}

在 运行 时间内加载 Hash128 的简单函数:

Hash128 getHash128(string path)
{
    //Load from the Resources folder
    TextAsset txtAsset = (TextAsset)Resources.Load(path, typeof(TextAsset));
    string hash128 = txtAsset.text;

    return Hash128.Parse(hash128);
}

使用方法:

//Load Hash128 from the Resources folder
Hash128 tempHash128 = getHash128("AssetInfo/AssetBundleInfo");

//Pass to the IsVersionCached function 
Caching.IsVersionCached("yourUrl", tempHash128);

您也可以使用json来表示并根据需要保存多个Hash128


2从服务器下载 AssetBundle,然后在 运行 时间内获取 Hash128,没有 Resources 文件夹。不幸的是,您必须先使用此方法下载 AssetBundle 才能获得其 Hash128。下载后,将数据加载为 AssetBundleManifest,然后使用 AssetBundleManifest.GetAssetBundleHash 函数从中获取 Hash128。然后您可以保存此 Hash128 以备后用。

下面的示例应该从 AssetBundle url 下载并提取 Hash128。不涉及编辑器代码。

IEnumerator downloadAssetBundle(string url)
{
    UnityWebRequest www = UnityWebRequest.GetAssetBundle(url);
    yield return www.SendWebRequest();

    if (www.isNetworkError || www.isHttpError)
    {
        Debug.Log(www.error);
    }
    else
    {
        //Get the AssetBundle
        AssetBundle bundle = DownloadHandlerAssetBundle.GetContent(www);

        AssetBundleRequest asset = bundle.LoadAssetAsync<AssetBundleManifest>("assetManifestName");
        yield return asset;

        //Get the AssetBundleManifest
        AssetBundleManifest loadedAssetMf = asset.asset as AssetBundleManifest;
        //Get Hash128 from the AssetBundleManifest
        Hash128 tempHash128 = loadedAssetMf.GetAssetBundleHash("");

        //Pass to the IsVersionCached function 
        Caching.IsVersionCached("yourUrl", tempHash128);
    }
}

3从文件系统中的 AssetBundle 获取 Hash128 如果您已经 AssetBundle 的路径,从该路径加载 AssetBundle,然后将数据加载为 AssetBundleManifest,最后用AssetBundleManifest.GetAssetBundleHash函数从中得到Hash128。然后您可以保存此 Hash128 以备后用。

这显示了如何从 StreamingAsset 路径加载 AssetBundle 并获取其 Hash128:

IEnumerator loadAssetManifest(string assetBundleName, string assetManifestName)
{
    string filePath = System.IO.Path.Combine(Application.streamingAssetsPath, "AssetBundles");
    filePath = System.IO.Path.Combine(filePath, assetBundleName);

    var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(filePath);
    yield return assetBundleCreateRequest;

    AssetBundle asseBundle = assetBundleCreateRequest.assetBundle;

    AssetBundleRequest asset = asseBundle.LoadAssetAsync<AssetBundleManifest>(assetManifestName);
    yield return asset;

    //Get the AssetBundleManifest
    AssetBundleManifest loadedAssetMf = asset.asset as AssetBundleManifest;
    //Get Hash128 from the AssetBundleManifest
    Hash128 tempHash128 = loadedAssetMf.GetAssetBundleHash("");

    //Pass to the IsVersionCached function 
    Caching.IsVersionCached("yourUrl", tempHash128);
}