Unity - How can I augment my Image Target with a model from an AssetBundle

January 6, 2014 - 3:54am #1

This article describes how to augment an image target with a custom 3D model instantiated at runtime, upon target detection, using the Vuforia Unity extension and the Prefab instantiation technique.

For more details about Unity Prefabs, please consult the Prefab guide on the Unity website:

http://docs.unity3d.com/Documentation/Manual/Prefabs.html

Steps:

  • Open/create a Unity project and import the Image targets sample package, and open the image target scene
  • Let’s assume, for ease if reference, that we want to dynamically attach (at runtime) a custom 3D model to the “chips” image target
  • Select the "chips" target and remove the exsiting teapot 3D object from the scene, so that the target has no children objects attached underneath
  • Create a C# script and define a class that implements the ITrackableEventHandler interface; this will allow to loada model from an AssetBundle at a specific URL and attach it to your "chips" Image Target at runtime; the following example shows how the code may look like:
public class AssetBundleAugmenter : MonoBehaviour, ITrackableEventHandler {

	public string AssetName;
	public int Version;

	private GameObject mBundleInstance = null;

	private TrackableBehaviour mTrackableBehaviour;

	private bool mAttached = false;

	void Start()
	{
		StartCoroutine(DownloadAndCache());

		mTrackableBehaviour = GetComponent<TrackableBehaviour>();
		if (mTrackableBehaviour)
		{
			mTrackableBehaviour.RegisterTrackableEventHandler(this);
		}
	}


	// Update is called once per frame
	IEnumerator DownloadAndCache() {
		while(!Caching.ready)
			yield return null;
		
		// example URL of file on PC filesystem (Windows)
		//string bundleURL = "file:///D:/Unity/AssetBundles/MyAssetBundle.unity3d";
		
		// example URL of file on Android device SD-card
		string bundleURL = "file:///mnt/sdcard/MyAndroidAssetBundle.unity3d";

		using (WWW www = WWW.LoadFromCacheOrDownload(bundleURL, Version)) {
			yield return www;
			
			if (www.error != null)
				throw new UnityException("WWW download had an error: " + www.error);
			
			AssetBundle bundle = www.assetBundle;
			if (AssetName == "") {
				mBundleInstance = Instantiate (bundle.mainAsset) as GameObject;
			}
			else {
				mBundleInstance = Instantiate(bundle.Load (AssetName)) as GameObject;
			}
		}
	}
	
	public void OnTrackableStateChanged(
		TrackableBehaviour.Status previousStatus,
		TrackableBehaviour.Status newStatus)
	{
		if (newStatus == TrackableBehaviour.Status.DETECTED ||
		    newStatus == TrackableBehaviour.Status.TRACKED ||
		    newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
		{
			if (!mAttached && mBundleInstance) {
				// if bundle has been loaded, let's attach it to this trackable
				mBundleInstance.transform.parent = this.transform;
				mBundleInstance.transform.localScale = new Vector3(0.3f, 0.3f, 0.3f);
				mBundleInstance.transform.localPosition = new Vector3(0.0f, 0.15f, 0.0f);
				mBundleInstance.transform.gameObject.SetActive(true);

				mAttached = true;
			}
		}
	}
}

 

Topic locked