Cancel Object.Instantiate

Hi,

I’m currently developing an AR app with Unity and Vuforia.
I’m loading the 3D objects from my server and instantiating them at the recognition of the image target.
Fact is that the objects are quite heavy and the instantiating can take up to 10s. If the user moves away from the target image during this lapse of time then the object is instantiate in front of the camera and will stay there anyway.

Here is how I Instantiate my objects:

		using(WWW www = new WWW(assetDwnLink))
		{
			yield return www;
			File.WriteAllBytes(Application.persistentDataPath + "/" + name, www.bytes);
			AssetBundle assetBundle = www.assetBundle;
			//GameObject gameobj = assetBundle.Load (name) as GameObject;
			request = assetBundle.LoadAsync (name, typeof(GameObject));
			yield return request;
			GO = Instantiate(request.asset) as GameObject;
			//GO = Instantiate(gameobj) as GameObject;
			GO.transform.parent = GameObject.Find("AugmentationObject").transform;
			GO.transform.localPosition = new Vector3(properties[0], properties[1], properties[2]);
			GO.transform.eulerAngles  = new Vector3(properties[3], properties[4], properties[5]);
			GO.transform.localScale = new Vector3(properties[6], properties[7], properties[8]);
			rotateAngles = new Vector3(properties[3], properties[4], properties[5]);
			distance = properties[6];
			zoomMin = properties[9];
			zoomMax = properties[10];
			zoomFacteur = properties[11];
			GO.SetActive(true);
			assetBundle.Unload(false);
			www.Dispose();
		}

And here’s how I’m actually destroying the object when the target is lost:

	public void OnTrackingLost()
	{
		Debug.Log ("OnTrackingLost called");
		if(GO)
		{
			Debug.Log("Destroy called");
			Destroy(GO);
		}
		else if(request != null && request.progress == 1)
		{
			request = null;
			Debug.LogError ("done");
		}
	}

After some hours reading the API, and reading about CancelInvoke etc. it doesn’t look like there’s a way to stop the Instantiate while it is instantiating…
Though, if any of way have an other idea of how to work around that, or know if I’m missing something, I’m listening to you!


As said in the answers I’m now using Async Loading so I can work with .progress and .isDone. But I can’t find the condition to use and the action to do to cancel the Instantiate.

Thanks a lot!

Maybe there’s some way you can break up the object you’re instantiating?

That way you can use an

IEnumerator StreamModel () {
    foreach (GameObject modelPart in listOfAssetbundles) {
        if (cancelBool == false) {
            Instantiate(modelPart);
        } else {
            yield break; //breaks if OnTrackingLost () { cancelBool = true; }
        }
        yield return null; //jumps to next frame for next part
    }
    yield return null;
}

or something to this affect, and now it will have maybe 1 second loads per chunk instead of 10 per complete model, letting your user cancel the loading with (as per the example) 1 second intervals instead of 10.

I found a workaround, I’m sure it’s not the best but at least I don’t have this problem anymore.
I’m using a bool which says whether the user is still pointing at the image target and I’m testing it before setting the GameObject active. If it’s false then I destroy the GO, if it’s true I set it active.

	public void OnTrackingLost()
	{
		Debug.Log ("OnTrackingLost called");
		if(GO)
		{
			Debug.Log("Destroy called");
			Destroy(GO);
		}
		else
		{
			outofcontext = true;
		}
	}

And in my augmentation method:

			if(!outofcontext)
			{
				Debug.LogError("On affiche");
				GO.SetActive(true);
			}
			else
			{
				Debug.LogError("On détruit");
				Destroy (GO);
			}

The bool is also set to false in the Start() method and to true in the OnTrackingFound() method.


After some hard testing, it appears that it keeps happening (very less often though), so to make sure I added that in the Update() method:

		if(outofcontext && GO != null)
		{
			Debug.LogError("On détruit");
			Handheld.StopActivityIndicator();
			Destroy (GO);
		}

I don’t have the problem at all anymore.