Asset Bundle: Failed to decompress data - Unity 5.6 - Windows Standalone 64

Hello everyone,

So I am relatively new to asset bundles, but it should be enough for what I need.
Previously, I had all my asset bundles hosted on my own private/testing server, and my client could download them without issues. Everything was working.

Today, I tried uploading the bundles to the client’s server, and now I get the error:
“Error while downloading Asset Bundle: Failed to decompress data for the AssetBundle”.

The link is right (if I type it in the url it downloads the bundle) and I haven’t changed any code, the only difference is the hosting server. My download goes up to 95%, then stops and gives me that error.

I have tried:

  • Recreating the bundles
  • Recreating them with BuildAssetBundleOptions set to None
  • Recreating them with BuildAssetBundleOptions set to ChunkBasedCompression
  • Recreating them with BuildAssetBundleOptions set to UncompressedAssetBundle

Do you guys have an idea of what I may be doing wrong? The client’s hosting service is Magnolia.

My code for bundle generation:

public class CreateAssetBundles : MonoBehaviour
{
    [MenuItem("Assets/Build AssetBundles for Windows _F6")]
    static void BuildAllAssetBundles()
    {
        string assetBundleDirectory = "Assets/AssetBundles/Windows";
        if(!Directory.Exists(assetBundleDirectory))
            Directory.CreateDirectory(assetBundleDirectory);

        BuildPipeline.BuildAssetBundles(assetBundleDirectory, BuildAssetBundleOptions.UncompressedAssetBundle, BuildTarget.StandaloneWindows64);
    }
}

My code for loading the bundle:

public IEnumerator DownloadBundleCoroutine(Action<GameObject> modelFound, string url, string modelName)
    {        
        uri = <confidential, but it is the right url.>;
        AssetBundle bundle = null;

        //I get versionOnServer from elsewhere, that isn't the problem.
        UnityWebRequest request = UnityWebRequest.GetAssetBundle(uri, (uint)versionOnServer, 0);
        request.Send();
        while (!request.isDone)
        {
             // Feedback on download progress. Goes up to 95% then breaks and outputs the error.
            onDLProgress?.Invoke(modelName, request.downloadProgress);
            yield return null;
        }

        // the error has already happened by the time it gets here
        bundle = DownloadHandlerAssetBundle.GetContent(request);
        GameObject model = null;
        if (bundle != null)
        {
            AssetBundleRequest newRequest = bundle.LoadAssetAsync<GameObject>(modelName);
            while (!newRequest.isDone)
            {
                Debug.Log("Loading");
                yield return null;
            }
            model = (GameObject)newRequest.asset;
        }
        modelFound(model);

        bundle.Unload(false);
        yield return null;
    }

Note: Each asset bundle only contains one asset, so I don’t need to bother with the manifest file AFAIK.

Thank you!

~LegendBacon

Had the same issue, 5.6+, and realized the files were uploaded using FileZilla, not in Binary mode. Re-uploaded in Binary mode and all was good. Test code below.

	------------
	string uri = "www.mywebsite.com/asset1";
	using (UnityWebRequest uwr = new UnityWebRequest(uri, UnityWebRequest.kHttpVerbGET))
	{
		uwr.chunkedTransfer = false; 
		uwr.SetRequestHeader("Accept", "*/*");
		uwr.SetRequestHeader("Accept-Language", "en-US");
		uwr.SetRequestHeader("Content-Language", "en-US");
		uwr.SetRequestHeader("Accept-Encoding", "gzip, deflate");
		uwr.SetRequestHeader("User-Agent", "runscope/0.1");
		uwr.downloadHandler = new DownloadHandlerAssetBundle(uri, 0);
		yield return uwr.SendWebRequest();
		assetBundle = DownloadHandlerAssetBundle.GetContent(uwr);
		if(assetBundle != null){

		}else{
			Debug.Log(uwr.error);
			Debug.Log(uwr.downloadHandler.text);
		}
	}

Hello everyone,

So for those following this question and in need of an answer, here is how I fixed this:

Apparently, Magnolia applies its own compression algorithm to files that need to be downloaded. It makes sense, but also makes asset bundles unusable.

The first solution is to upload the file as a .zip file, download it, and unzip it at runtime, which adds a little overhead and can be little slow on some devices.

The second, and one I ended up using, is to use the WWW class instead of UnityWebRequest. It doesn’t come with that neat .GetAssetBundle(), but at least it works. Here is my working code:

uri = <Confidential. Direct link to the file on server>;

        WWW bundleRequest = new WWW(uri);
        while (!bundleRequest.isDone)
        {
            Debug.Log("downloading....");
            onDLProgress?.Invoke(modelName, bundleRequest.progress);
            yield return null;
        }

        AssetBundle bundle = null;
        if (bundleRequest.bytesDownloaded > 0)
        {
            AssetBundleCreateRequest myRequest = AssetBundle.LoadFromMemoryAsync(bundleRequest.bytes);
            while(!myRequest.isDone)
            {
                Debug.Log("loading....");
                yield return null;
            }
            if(myRequest.assetBundle != null)
            {
                bundle = myRequest.assetBundle;
                GameObject model = null;
                if (bundle != null)
                {
                    AssetBundleRequest newRequest = bundle.LoadAssetAsync<GameObject>(modelName);
                    while (!newRequest.isDone)
                    {
                        Debug.Log("loading ASSET....");
                        yield return null;
                    }
                    model = (GameObject)newRequest.asset;
                    modelFound(model);

                    bundle.Unload(false);
                }
            }
            else
            {
                Debug.LogError("COULDN'T DOWNLOAD ASSET BUNDLE FROM URL: " + uri);
                modelFound(null);
            }
        }
        else
        {
            Debug.LogError("COULDN'T DOWNLOAD ASSET BUNDLE FROM URL: " + uri);
            modelFound(null);
        }

Kind of a pain, but everything works asynchronously. I do have to build my own cache though, as now the bundle is downloaded every time instead of getting loaded from cache if the revision numbers match.

Hope that can help other people!

~LegendBacon