简体   繁体   中英

Lag when loading downloaded AssetBundle

I've updated to Unity 2017.1. When I instantiate an object on scene from bundle the app freezes for 1-3 seconds. I didn't notice this problem on previous Unity version, but I don't want to downgrade to 5.6.

IEnumerator LoadAssetBundle(WWW www)
{
    EventLisaner.Instance.SetAudioStation(false);
    while (!www.isDone)
    {
        int current = (int)(www.progress * 100);
        progressText.text = string.Format("Загрузка модели {0}%", current.ToString());
        yield return null;
    }
    yield return www;

    if (www.error == null)
    {
        if (bundle != null)
        {
            Destroy(destroyBundle);
            bundle.Unload(true);

        }
        bundle = www.assetBundle;
        StartCoroutine(InstantiationBundle());
    }
    else
    {
        loaderUI.SetActive(false);
    }
}

private IEnumerator InstantiationBundle()
{
    GameObject inst = bundle.LoadAsset("prefab") as GameObject;
    GameObject obj = Instantiate(inst);

    obj.transform.SetParent(RayCam.selectObj.transform.parent, false);
    obj.AddComponent<VuforiaMove>();
    loaderUI.SetActive(false);
    destroyBundle = obj;
    EventLisaner.Instance.enabledLoadBundle = true;
    EventLisaner.Instance.enbledNextTrekingDonload = true;
    yield return null;
}

UPD: I've determined that bug appears on this line: bundle = www.assetBundle; . I've tried to do yield return bundle = www.assetBundle; but it didn't seem to help. Still having that freeze.

The only line of code that can cause this freeze is bundle.LoadAsset .This is loading and de-serializing the AssetBundle in the main thread. You have to use the async version of this function which is LoadAssetAsync then yield it to finish loading. It will do the loading in another thread. The coroutine is simply used to wait for that operation being performed in another thread to finish.

Replace

GameObject inst = bundle.LoadAsset("prefab") as GameObject;

with

AssetBundleRequest request = bundle.LoadAssetAsync("prefab");
//Wait for load
yield return request;
GameObject inst = request.asset as GameObject;

The rest of the code should be the-same.

EDIT :

If www.assetBundle is causing the issue, remove that line of code and use AssetBundle.LoadFromMemoryAsync(www.bytes) to load the Assetbundle. you will have to pass WWW to the InstantiationBundle function.

private IEnumerator InstantiationBundle(WWW www)
{
    AssetBundleCreateRequest createRequest = AssetBundle.LoadFromMemoryAsync(www.bytes);
    yield return createRequest;

    AssetBundle bundle = createRequest.assetBundle;

    AssetBundleRequest request = bundle.LoadAssetAsync("prefab");
    //Wait for load
    yield return request;
    GameObject inst = request.asset as GameObject;

    ....
    .....
    yield return null;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM