5
\$\begingroup\$

I have a Unity WebGL project that tries to load AssetBundles, but I get an error:

Unable to open archive file: http://localhost:50212/StreamingAssets/Bundles/language_english

The code that creates the AssetBundles:

using UnityEditor;
using System.IO;
using UnityEngine;

public class JC_Bundler: Editor
{
    [MenuItem("Assets/Build AssetBundles")]
    static void BuildAllAssetBundles()
    {
        string path = Path.Combine(Application.streamingAssetsPath, JC_Bundles.Directory);
        if (!Directory.Exists(path))
        {
            Directory.CreateDirectory(path);
        }

        BuildPipeline.BuildAssetBundles(path, BuildAssetBundleOptions.None, EditorUserBuildSettings.activeBuildTarget);
        AssetDatabase.Refresh();
    }
}

I can see the AssetBundles do get created and it works on other Windows Standalone and Android platforms.

The code that read the AssetBundle:

public void PrepareLanguageAssets(SystemLanguage language, UnityAction onDone, UnityAction onFail)
{
    StartCoroutine(LoadBundle("language_" + language, bundle => {
        if (bundle == null)
        {
            onFail();
        }
        else
        {
            if (languageBundle) languageBundle.Unload(true);
            languageBundle = bundle;
            onDone();
        }
    }));
}

public void LoadLanguageAsset<T>(String name, UnityAction<T> callback) where T : UnityEngine.Object
{
    StartCoroutine(LoadAsset(languageBundle, name, callback));
}

IEnumerator LoadAsset<T>(AssetBundle bundle, string objectNameToLoad, UnityAction<T> callback) where T: UnityEngine.Object
{
    AssetBundleRequest asset = bundle.LoadAssetAsync<T>(objectNameToLoad);
    yield return asset;

    callback(asset.asset as T);
}

So when I switch my Unity Editor Platform to WebGL and do a "Build And Run" with the same project I see the above mentioned error.

How can I load AssetBundles in WebGL?

\$\endgroup\$

1 Answer 1

4
\$\begingroup\$

Got it working with the following LoadBundle method:

IEnumerator LoadBundle(string bundleName, UnityAction<AssetBundle> callback)
{
    string path = Path.Combine(Application.streamingAssetsPath, Directory, bundleName.ToLower());
    Debug.Log(path);
#if UNITY_WEBGL && !UNITY_EDITOR
    UnityWebRequest request = UnityWebRequestAssetBundle.GetAssetBundle(path);
    yield return request.SendWebRequest();

    if (request.isNetworkError || request.isHttpError)
    {
        Debug.LogError(request.error);
    }
    else
    {
        // Get downloaded asset bundle
        callback(DownloadHandlerAssetBundle.GetContent(request));
    }
#else
    var assetBundleCreateRequest = AssetBundle.LoadFromFileAsync(path);
    yield return assetBundleCreateRequest;
    callback(assetBundleCreateRequest.assetBundle);
#endif
}

It seems like WebGL cannot open bundles with AssetBundle.LoadFromFileAsync(path), but the UnityWebRequestAssetBundle.GetAssetBundle(path) works. It is probably a better approach for WebGL anyways.

\$\endgroup\$
2
  • \$\begingroup\$ Life saving! Thank you ❤️ \$\endgroup\$
    – Bilal Akil
    Apr 11, 2020 at 7:38
  • \$\begingroup\$ This is quite an old answer. In the meantime Unity also released an Addressables package which does the same job and has a few additional advantages above Asset Bundles. However it seems like it is still heavy under development, but as far as I can tell the latest release seems stable. You may consider using that. \$\endgroup\$ Apr 11, 2020 at 11:05

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .