我有一个非常大的3D世界/环境
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则对已加载包的游戏对象(如果可用)执行deactive。以下是用于下载资产包的代码段:
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;
}
并且为了销毁(实际上停用对象,因为破坏是昂贵的功能)捆绑。
代码工作正常,我能够加载/卸载资产包但问题是
任何人都可以帮我写更高效,更优雅的方式来加载/卸载资产包吗?
您首先应该查看分析器并查看应用程序的阻塞点,如果它在加载捆绑包时停留(协同程序仍在主线程上运行并且可能导致滞后)您可能想要使用async loading。但是你想要提前打电话给那些(当玩家接近另一个大块时,所以当他实际到达大块时就准备好了)。如果您的瓶颈位于其他地方,例如与渲染有关的事情,您可能会以其他方式接近它(较小的资产具有较少的顶点/三角形或更积极的剔除)。无论哪种方式更好的判断你需要找到问题的位置,但从第一眼看,似乎在主线程上加载资产是问题。