我在另一个项目中分离了一些小游戏,以便将它们全部加载到一个项目中。我已经使用 Unity 2018.4.9 版本成功创建了资产包,并将它们放入 StreamingAssets 文件夹中。Unity Editor成功加载和卸载场景,但是当我构建IOS时,成功加载场景,没问题,但是当我想卸载它时,它给了我这样的内存错误:
I think this error occurs when system tries to delete a gameobject related with asset bundles. Because when I want to delete all gameobjects in scene before unloading scene, it gives same error. This error only occurs in iOS, not Editor. Unity Editor unloads asset bundle scenes succesfully. Here my code to load/unload asset bundles and their scenes :
Error occurs when I run UnloadAdditiveScene()
using System.Collections;
using System.Collections.Generic;
using System.IO;
using UnityEngine;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class MarketplaceBundleGameLoader : MonoBehaviour
{
AssetBundle myLoadAssetBundle;
AssetBundle[] assetBundles;
float progress = 0f;
List<GameObject> objectsToBeDisabled;
public bool passingToAnotherScene = false;
public static string bundlePath;
public static MarketplaceBundleGameLoader Instance;
void Awake()
{
if (Instance == null)
{
Instance = this;
objectsToBeDisabled = new List<GameObject>();
DontDestroyOnLoad(gameObject);
}
else
{
DestroyImmediate(gameObject);
}
}
public void AddObjectToBeDisabled(GameObject go)
{
objectsToBeDisabled.Add(go);
}
public void LoadMultipleBundles(params string[] pathes)
{
if (passingToAnotherScene)
{
return;
}
passingToAnotherScene = true;
StartCoroutine(LoadMultipleBundlesTask(pathes));
}
IEnumerator LoadMultipleBundlesTask(params string[] pathes)
{
progress = 0;
assetBundles = new AssetBundle[pathes.Length];
Resources.UnloadUnusedAssets();
yield return FaderManager.Instance.CloseTheatre();
for (int i = 0; i < objectsToBeDisabled.Count; i++)
{
objectsToBeDisabled[i].SetActive(false);
}
SceneManager.LoadScene("BundleGameLoader", LoadSceneMode.Additive);
yield return FaderManager.Instance.OpenTheatre();
for (int i = 0; i < pathes.Length; i++)
{
AssetBundleCreateRequest abcr = AssetBundle.LoadFromMemoryAsync(File.ReadAllBytes(Path.Combine(StaticVariables.GetStreamingPath(), pathes[i])));
while (abcr.progress < 0.9f)
{
progress = (i / (1f + pathes.Length)) + abcr.progress / (1f + pathes.Length);
yield return new WaitForFixedUpdate();
}
assetBundles[i] = abcr.assetBundle;
}
string[] scenePath = assetBundles[0].GetAllScenePaths();
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(System.IO.Path.GetFileNameWithoutExtension(scenePath[0]), LoadSceneMode.Additive);
asyncLoad.allowSceneActivation = false;
float totalTimer = 0f;
while (asyncLoad.progress < 0.9f)
{
totalTimer += Time.deltaTime;
progress = ((float)pathes.Length / (pathes.Length + 1)) + asyncLoad.progress / (pathes.Length + 1);
yield return null;
}
progress = 1.05f;
float waitDifferenceTime = Mathf.Max(0.1f, 3f - totalTimer);
yield return new WaitForSeconds(waitDifferenceTime);
Resources.UnloadUnusedAssets();
yield return FaderManager.Instance.CloseTheatre();
asyncLoad.allowSceneActivation = true;
AsyncOperation asyncUnload = SceneManager.UnloadSceneAsync(SceneManager.GetSceneByName("BundleGameLoader"));
while (asyncUnload.progress < 0.9f)
{
yield return null;
}
passingToAnotherScene = false;
yield return FaderManager.Instance.OpenTheatre();
}
public float GetProgress()
{
return progress;
}
public void UnloadAdditiveScene(string unloadName)
{
StartCoroutine(UnloadAdditiveSceneSceneTask(unloadName));
}
IEnumerator UnloadAdditiveSceneSceneTask(string unloadName)
{
yield return FaderManager.Instance.CloseTheatre();
for (int i = 0; i < assetBundles.Length; i++)
{
assetBundles[i].Unload(false);
}
yield return new WaitForEndOfFrame();
AsyncOperation asyncUnload = SceneManager.UnloadSceneAsync(unloadName);
while(!asyncUnload.isDone)
{
yield return new WaitForEndOfFrame();
}
yield return new WaitForEndOfFrame();
SceneManager.SetActiveScene(SceneManager.GetSceneAt(0));
//AssetBundle.UnloadAllAssetBundles(true);
// AssetBundle[] bundles = Resources.FindObjectsOfTypeAll<AssetBundle>();
// //Debug.Log(bundles.Length);
// for (int i = 1; i < bundles.Length; i++)
// {
// bundles[i].Unload(true);
// }
//Resources.UnloadUnusedAssets();
for (int i = 0; i < objectsToBeDisabled.Count; i++)
{
objectsToBeDisabled[i].SetActive(true);
}
objectsToBeDisabled.Clear();
yield return FaderManager.Instance.OpenTheatre();
}
// public void loadScene(string sceneName)
// {
// if(passingToAnotherScene)
// {
// return;
// }
// passingToAnotherScene = true;
// StartCoroutine(loadSceneTask(sceneName));
// }
// public IEnumerator loadSceneTask(string sceneName)
// {
// yield return FaderController.Instance.fadeScreen(0.5f);
// yield return new WaitForSeconds(0.5f);
// SceneManager.LoadScene("SeasonsLoading");
// yield return FaderController.Instance.unfadeScreen(0.5f);
// AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName);
// asyncLoad.allowSceneActivation = false;
// float totalTimer = 0f;
// while(asyncLoad.progress < 0.9f)
// {
// totalTimer += Time.deltaTime;
// yield return null;
// }
// float waitDifferenceTime = Mathf.Max(0.1f, 3f - totalTimer);
// yield return new WaitForSeconds(waitDifferenceTime);
// yield return FaderController.Instance.fadeScreen(0.5f);
// asyncLoad.allowSceneActivation = true;
// passingToAnotherScene = false;
// yield return FaderController.Instance.unfadeScreen(0.5f);
// //yield return new WaitForSeconds(0.5f);
// }
public void RestartScene(string sceneName)
{
if (passingToAnotherScene)
{
return;
}
passingToAnotherScene = true;
StartCoroutine(RestartSceneTask(sceneName));
}
public IEnumerator RestartSceneTask(string sceneName)
{
yield return FaderManager.Instance.CloseTheatre();
AsyncOperation asyncUnload = SceneManager.UnloadSceneAsync(SceneManager.GetSceneByName(sceneName));
while (asyncUnload.progress < 0.9f)
{
yield return null;
}
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(sceneName, LoadSceneMode.Additive);
while (asyncLoad.progress < 0.9f)
{
yield return null;
}
passingToAnotherScene = false;
yield return FaderManager.Instance.OpenTheatre();
}
public void ChangeScene(string unloadScene, string loadScene)
{
if (passingToAnotherScene)
{
return;
}
passingToAnotherScene = true;
StartCoroutine(ChangeSceneTask(unloadScene, loadScene));
}
public IEnumerator ChangeSceneTask(string unloadScene, string loadScene)
{
yield return FaderManager.Instance.CloseTheatre();
AsyncOperation asyncUnload = SceneManager.UnloadSceneAsync(SceneManager.GetSceneByName(unloadScene));
while (asyncUnload.progress < 0.9f)
{
yield return null;
}
AsyncOperation asyncLoad = SceneManager.LoadSceneAsync(loadScene, LoadSceneMode.Additive);
while (asyncLoad.progress < 0.9f)
{
yield return null;
}
passingToAnotherScene = false;
yield return FaderManager.Instance.OpenTheatre();
}
}
Disabling "Strip Engine Code" option in Player Settings solved my problem. In 2018.3.4, when you disable this option, Xcode gives linker error. But in 2019.2.6f, it works.
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句