【发布时间】:2019-04-08 09:26:17
【问题描述】:
我有一个非常大型 3D 世界/环境
我已分成 1000 x 1000 m (1km) 的图块。
制作所有图块的assetbundles,目前只有5个asset bundles(预计会大幅增长,可能在1000左右 资产包)。
- 加载\卸载这些资产包,我正在计算我的播放器/相机与瓷砖的距离,然后调用 加载或卸载。
请看下面的简单脚本(根据距离加载图块):
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 停用加载包的游戏对象(如果可用)。 以下是用于下载资产包的代码 sn-p:
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;
}
为了销毁(实际上将对象作为销毁是昂贵的功能而停用)捆绑包。
性能问题:
代码运行良好,我可以加载/卸载资产包但问题是
它的性能不好(循环预计会增长)。
Webgl 有时会很长,而且运行不流畅。
- 下载内容(资产包)时,尽管使用了 LoadAssetAsync,但游戏仍会冻结。
谁能帮我写出更高效、更优雅的方式来加载/卸载资产包?
【问题讨论】:
-
@MuhammadFaizanKhan ,我很困惑,为什么不使用 GetAssetBundle ?或者这种事情docs.unity3d.com/540/Documentation/Manual/…我只是看了你的问题...对不起..
-
@Fattie 实际上我正在使用 GetAssetBundle。我已经更新了之前缺少的实际资产包加载代码。
-
这个问题和the one you asked on GameDev有什么不同?
-
如果你仔细观察,我提到的编码 sn-p 是有区别的。
标签: c# unity3d unity-webgl assetbundle