使用资产捆绑包在统一WebGL中进行巨大的世界装卸 [英] Huge world loading/unloading in unity webgl using asset bundles

查看:115
本文介绍了使用资产捆绑包在统一WebGL中进行巨大的世界装卸的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常强大的大型3D世界/环境

  1. 我已划分为1000 x 1000 m(1公里)的瓷砖.

所有图块的资产捆绑包,目前只有5个资产捆绑包(预计将显着增长,可能约为1000 资产捆绑包).

Made assetbundles of all tiles and currently there are only 5 asset bundles (Expected to grow significantly maybe around 1000 asset bundles).

请参见下面的简单脚本(根据距离加载图块):

        public Vector3 tileSize;
        public int maxDistance;
        public MultipleAssetBundleLoader[] tiles;

        void Start()
        {
            this.tiles  = FindObjectsOfType<MultipleAssetBundleLoader>();
        }

        void DeactivateDistantTiles()
        {
                foreach (MultipleAssetBundleLoader tile in tiles)
                {
                    Vector3 tilePosition = tile.gameObject.transform.position + (tileSize / 2f);

                    float xDistance = Mathf.Abs(tilePosition.x - playerPosition.x);
                    float zDistance = Mathf.Abs(tilePosition.z - playerPosition.z);

                    if (xDistance + zDistance > maxDistance)
                    {
                        tile.DestroyBundleObject();
                        //tile.SetActive(false);
                    }
                    else
                    {
                        tile.StartDownloadingAB();
                    }
                }  
        }

        void Update()
        {
            DeactivateDistantTiles();
        }

函数 StartDownloadingAB 只需下载资产捆绑包并从服务器或缓存实例化游戏对象,而DestroyBundleObject停用已加载捆绑包的游戏对象(如果可用). 以下是用于下载资产捆绑包的代码段:

The function StartDownloadingAB simply download the asset bundles and instantiate game object from server or cache while DestroyBundleObject deactive the game object of the loaded bundle (if available). Here are code snippet for download the asset bundle:

public void StartDownloadingAB()
        {
            if (BundleLoadStatus == BundleLoadStatusEnum.bundleNotLoadedYet)
            {
                BundleLoadStatus = BundleLoadStatusEnum.bundlesLoading;
                downloadABRef = StartCoroutine(DownloadAB());
            }
            else if (bundleObjectsDeactivated == true && BundleLoadStatus == BundleLoadStatusEnum.bundlesHasLoaded)
            {
                BundleObjectActive(true);
            }
        }

public IEnumerator DownloadAB()
{

    if (isBundleLoading == true)
        yield return false;

    BundleLoadStatus = BundleLoadStatusEnum.bundlesLoading;
    isBundleLoading = true;

    //Debug.Log("loading " + url);
    www = UnityWebRequestAssetBundle.GetAssetBundle(url);
    yield return www.SendWebRequest();

    if (www.error != null)
    {
        Debug.LogError("assetBundleURL : " + url);
        Debug.LogError("www error : " + www.error);
        www.Dispose();
        www = null;
        yield break;
    }

    AssetBundle bundle = ((DownloadHandlerAssetBundle)www.downloadHandler).assetBundle;

    GameObject bundlePrefab = null;
    bundlePrefab = (GameObject)bundle.LoadAsset(bundle.name);
    AssetBundleRequest bundlePrefabAsync = bundle.LoadAssetAsync(bundle.name, typeof(GameObject));
    yield return bundlePrefab;

    if (bundlePrefab != null)
    {

        //assetBundleToLoadObj = (GameObject)Instantiate(bundlePrefab);
        assetBundleToLoadObj = Instantiate(bundlePrefabAsync.asset as GameObject);
        assetBundleToLoadObj.transform.parent = envParent.transform;

        floorL7MeshRenderer.enabled = false;
    }

    www.Dispose();
    www = null;

    // try to cleanup memory
    Resources.UnloadUnusedAssets();
    bundle.Unload(false);
    //bundle = null;

    isBundleLoading = false;
    BundleLoadStatus = BundleLoadStatusEnum.bundlesHasLoaded;
}

并且对于销毁(实际上将对象作为销毁来停用对象是一项昂贵的功能)

And For Destroying (actually deactivating the object as destroy is expensive function) the bundle.

代码运行正常,我能够加载/卸载资产捆绑包,但问题是

The code is working fine and I am able to load/unload the asset bundle But the problems are

  1. 它的性能不好(该循环有望增长).

  1. its performance is not good (The loop is expected to grow).

Webgl有时笨拙,并且运行不流畅或无法顺利运行.

The Webgl is leggy sometime and it is not seamless or smoothly runs.

有人可以帮我写出更有效,更优雅的方式来加载/卸载资产包吗?

Can anyone help me to write more efficient and elegant way to load/unload asset bundle ?

推荐答案

如果应用程序滞留在加载包中,则应该首先查看分析器并查看应用程序的阻塞点(协程仍在主程序上运行线程并可能导致滞后),则可能要使用异步加载.但是您可能想提前调用它们(当玩家靠近另一个块时,因此当他实际到达该块时就已经准备好了). 如果瓶颈处在其他位置,例如与渲染相关的操作,您可能会采用其他方式(较小的资产/较少的顶点/三角形或更具侵略性的剔除).无论哪种方法,您都需要找到问题所在,但从第一眼看,似乎在主线程上加载资产是问题所在.

You should first of all look at the profiler and see the choke points of your application, if it is stuck at loading bundles (coroutines are still run on the main thread and might cause lags) you might want to use async loading. But you would want to call those ahead of time (when player is NEAR the other chunk, so its ready when he actually reaches the chunk). If your bottlenecks lies somewhere else, for example something to do with rendering you might approach it some other way (smaller assets with less vertices/triangles or more aggressive culling). Either way for better judgement you need to locate where the problem is, but from the first look it seems that loading the asset on main thread is the problem.

这篇关于使用资产捆绑包在统一WebGL中进行巨大的世界装卸的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆