Log in or register to post comments

gameobject visible on tracking lost also

February 3, 2014 - 5:36am #1

Hi there!

I am using Cloud Reco Sample 2.8.9 with Unity 4.2.1. I am downloading the 3D asset bundles from server using the detected target image name,

detectedTargetName = targetSearchResult.TargetName;

and a predefined link to download an asset for the detected target, and am NOT using metadata. The 3D asset is instantiated properly and is also augmented but the problem is, when the image target is lost the renderers are not turning off and the augmentation content stays visible on the screen. I debugged my code to see if the code enters into "OnStateChanged(bool scanning)" method in CloudRecoEventHandler script and "ShowObject(bool tf)" in ContentManager script. It does not....

Below is the ContentManager script,

/*==============================================================================
Copyright (c) 2012-2013 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
==============================================================================*/

using UnityEngine;
using System.Collections;
using System.Timers;
using SimpleJSON;
using System.Collections.Generic;
using System.IO;

/// <summary>
/// This class manages the content displayed on top of cloud reco targets in this sample
/// </summary>
public class dummyContentManager : MonoBehaviour, ITrackableEventHandler
{
    #region PUBLIC_VARIABLES
    /// <summary>
    /// The root gameobject that serves as an augmentation for the image targets created by search results
    /// </summary>
    //public GameObject AugmentationObject;
    #endregion PUBLIC_VARIABLES
	
	//-----------------------------------------------------------------------------------------------
	bool FirstTime;
	public static bool Lost;
	public static string statusIndicator;
	public static GameObject GO;
	public static bool startTracking;
	
	//Asset bundle download link
	public static string assetDwnLink;
	//set link to download asset bundle depending on device platform
#if UNITY_ANDROID
    public static string assetDwnLinkPrefix = "http://android_link";
#endif
		
#if UNITY_IPHONE
	public static string assetDwnLinkPrefix = "http://iOS_link";
#endif
	
	
	//-----------------------------------------------------------------------------------------------
	
    #region UNTIY_MONOBEHAVIOUR_METHODS

    void Start ()
    {
		FirstTime = true;
		startTracking = true;
		TrackableBehaviour trackableBehaviour = GetComponent<TrackableBehaviour>();
		
		if (trackableBehaviour)
        {
            trackableBehaviour.RegisterTrackableEventHandler(this);
        }
        
        ShowObject(false);
    }
	
	void OnGUI ()
	{
		GUI.Label(new Rect (Screen.width/2-50, Screen.height/2-30, 100, 60), ""+statusIndicator);
		GUI.Label(new Rect (Screen.width/2-50, Screen.height/2+30, 100, 60), ""+dummyCloudRecoEventHandler.detectedTargetName);
	}
    
    #endregion UNTIY_MONOBEHAVIOUR_METHODS
	
	
	
    #region PUBLIC_METHODS
    
    /// <summary>
    /// Implementation of the ITrackableEventHandler function called when the
    /// tracking state changes.
    /// </summary>
    public void OnTrackableStateChanged(
                                    TrackableBehaviour.Status previousStatus,
                                    TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED || 
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            ShowObject(true);
        }
        else
        {
            ShowObject(false);
        }
    }
    
	public void ShowObject(bool tf)
    {	
		if(startTracking && tf)
		{
			Lost = false;
			//when the image tracker is tracked for the first time, variable "FirstTime" is true. So at that time only we have to check for 3D models.
			if(FirstTime)
			{
				StartCoroutine(assign3DModel(assetDwnLinkPrefix, dummyCloudRecoEventHandler.detectedTargetName));
				FirstTime = false;
			}
	
			Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
	        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
	        // Enable rendering:
	        foreach (Renderer component in rendererComponents)
	        {
	            component.enabled = true;
	        }
	        // Enable colliders:
	        foreach (Collider component in colliderComponents)
	        {
	            component.enabled = true;
	        }
		}
		else if(tf == false)
		{
			Debug.Log("----------------------tf: "+tf + " should disable and destroy gameobjGo now");
			Lost = true;
	        // Enable rendering:
	        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
	        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
			foreach (Renderer component in rendererComponents)
	        {
	            component.enabled = false;
	        }
	        // Enable colliders:
	        foreach (Collider component in colliderComponents)
	        {
	            component.enabled = false;
	        }
			Destroy(GO);
		}
		
    }
	
	#endregion PUBLIC_METHODS
	
	
	#region ASSIGN 3D MODEL
	//This method downloads asset bundle from server and instantiates it
	
	IEnumerator assign3DModel(string assetDwnLinkPrefix, string detectedTargetName)
	{
		//assetDwnLinkPrefix is the download link
		string assetDwnLink = assetDwnLinkPrefix + detectedTargetName + ".unity3d";
		
		using(WWW www = new WWW(assetDwnLink))
		{
			yield return www;
			File.WriteAllBytes(Application.persistentDataPath + "/" + detectedTargetName, www.bytes);
        	AssetBundle assetBundle = www.assetBundle;
        	GameObject gameobj = assetBundle.mainAsset as GameObject; 
        	GO = Instantiate(gameobj) as GameObject;
        	GO.transform.parent = GameObject.Find("CloudRecoTarget").transform;
			GO.SetActive(true);
			assetBundle.Unload(false);
		}
   	}
	
	
	
	#endregion ASSIGN 3D MODEL
	
}

Below is my CloudRecoEventHandler script,

/*==============================================================================
Copyright (c) 2012-2013 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
==============================================================================*/

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;

/// <summary>
/// This MonoBehaviour implements the Cloud Reco Event handling for this sample.
/// It registers itself at the CloudRecoBehaviour and is notified of new search results as well as error messages
/// The current state is visualized and new results are enabled using the TargetFinder API.
/// </summary>
public class dummyCloudRecoEventHandler : MonoBehaviour, ICloudRecoEventHandler
{
    #region PRIVATE_MEMBER_VARIABLES

    // ImageTracker reference to avoid lookups
    private ImageTracker mImageTracker;
    private ContentManager mContentManager;
	private CloudRecoBehaviour mCloudRecoBehaviour;
	
	
	//Asset bundle download link
	public static string detectedTargetName;
	
	//to call ShowObject() only once
	public static bool firsttimeShow;
	
	
	//The parent gameobject of the referenced ImageTargetTemplate - reused for all target search results
    private GameObject mParentOfImageTargetTemplate;

    #endregion // PRIVATE_MEMBER_VARIABLES



    #region EXPOSED_PUBLIC_VARIABLES

    /// <summary>
    /// can be set in the Unity inspector to reference a ImageTargetBehaviour that is used for augmentations of new cloud reco results.
    /// </summary>
    public ImageTargetBehaviour ImageTargetTemplate;

    #endregion

    #region ICloudRecoEventHandler_IMPLEMENTATION

    /// <summary>
    /// called when TargetFinder has been initialized successfully
    /// </summary>
    public void OnInitialized()
    {
        // get a reference to the Image Tracker, remember it
        mImageTracker = TrackerManager.Instance.GetTracker<ImageTracker>();
        mContentManager = (ContentManager)FindObjectOfType(typeof(ContentManager));
    }

    /// <summary>
    /// visualize initialization errors
    /// </summary>
    public void OnInitError(TargetFinder.InitState initError)
    {
        switch (initError)
        {
            case TargetFinder.InitState.INIT_ERROR_NO_NETWORK_CONNECTION:
                ErrorMsg.New("Network Unavailable", "Please check your internet connection and try again.", RestartApplication);
                break;
            case TargetFinder.InitState.INIT_ERROR_SERVICE_NOT_AVAILABLE:
                ErrorMsg.New("Service Unavailable", "Failed to initialize app because the service is not available.");
                break;
        }
    }
    
    /// <summary>
    /// visualize update errors
    /// </summary>
    public void OnUpdateError(TargetFinder.UpdateState updateError)
    {
        switch (updateError)
        {
            case TargetFinder.UpdateState.UPDATE_ERROR_AUTHORIZATION_FAILED:
                ErrorMsg.New("Authorization Error","The cloud recognition service access keys are incorrect or have expired.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_NO_NETWORK_CONNECTION:
                ErrorMsg.New("Network Unavailable","Please check your internet connection and try again.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_PROJECT_SUSPENDED:
                ErrorMsg.New("Authorization Error","The cloud recognition service has been suspended.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_REQUEST_TIMEOUT:
                ErrorMsg.New("Request Timeout","The network request has timed out, please check your internet connection and try again.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_SERVICE_NOT_AVAILABLE:
                ErrorMsg.New("Service Unavailable","The service is unavailable, please try again later.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_TIMESTAMP_OUT_OF_RANGE:
                ErrorMsg.New("Clock Sync Error","Please update the date and time and try again.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_UPDATE_SDK:
                ErrorMsg.New("Unsupported Version","The application is using an unsupported version of Vuforia.");
                break;
        }
    }

    /// <summary>
    /// when we start scanning, unregister Trackable from the ImageTargetTemplate, then delete all trackables
    /// </summary>
    public void OnStateChanged(bool scanning)
    {
        if (scanning)
        {
			Debug.Log("scanning value-------------"+scanning);
            // clear all known trackables
            mImageTracker.TargetFinder.ClearTrackables(false);

            // hide the ImageTargetTemplate
            mContentManager.ShowObject(false);
			mCloudRecoBehaviour.CloudRecoEnabled = true;
        }
    }
    
    /// <summary>
    /// Handles new search results
    /// </summary>
    /// <param name="targetSearchResult"></param>
    
	public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)
    {
        // First clear all trackables
        mImageTracker.TargetFinder.ClearTrackables(false);
		
		//Tracking found via CLOUD, AR content download and instantiation function is called from here
		detectedTargetName = targetSearchResult.TargetName;
		
		if(firsttimeShow)
		{
			mContentManager.ShowObject(true);
			firsttimeShow = false;
		}
		
        // enable the new result with the same ImageTargetBehaviour:
        ImageTargetBehaviour imageTargetBehaviour = mImageTracker.TargetFinder.EnableTracking(targetSearchResult, mParentOfImageTargetTemplate) as ImageTargetBehaviour;
		
		if (imageTargetBehaviour != null)
		{
		    mCloudRecoBehaviour.CloudRecoEnabled = false;
		}
		
		//if extended tracking was enabled from the menu, we need to start the extendedtracking on the newly found trackble.
		if(CloudRecognitionUIEventHandler.ExtendedTrackingIsEnabled)
		{
			imageTargetBehaviour.ImageTarget.StartExtendedTracking();
		}
    }
	
	#endregion // ICloudRecoEventHandler_IMPLEMENTATION



    #region UNTIY_MONOBEHAVIOUR_METHODS

    /// <summary>
    /// register for events at the CloudRecoBehaviour
    /// </summary>
    void Start()
    {
		firsttimeShow = true;
		// look up the gameobject containing the ImageTargetTemplate:
        mParentOfImageTargetTemplate = ImageTargetTemplate.gameObject;

        // intialize the ErrorMsg class
        ErrorMsg.Init();

        // register this event handler at the cloud reco behaviour
        CloudRecoBehaviour cloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();
        if (cloudRecoBehaviour)
        {
            cloudRecoBehaviour.RegisterEventHandler(this);
        }
		
		// remember cloudRecoBehaviour for later
        mCloudRecoBehaviour = cloudRecoBehaviour;
    }

    /// <summary>
    /// draw the sample GUI and error messages
    /// </summary>
    void OnGUI()
    {
        // draw error messages in case there were any
        ErrorMsg.Draw();
    }

    #endregion UNTIY_MONOBEHAVIOUR_METHODS

    #region PRIVATE_METHODS
    
    // callback for network-not-available error message
    private void RestartApplication()
    {
        Application.LoadLevel("Vuforia-1-About");
    }
    #endregion PRIVATE_METHODS
}

Any idea, why is the compiler not entering these methods? Or how to solve this issue?

Any help would be much appreciated.

Thanks in advance!

gameobject visible on tracking lost also

March 13, 2017 - 12:37am #29

HOW to do ? not able to do..

 

gameobject visible on tracking lost also

November 28, 2016 - 12:06am #28

Worked perfect :) Thanks :)

gameobject visible on tracking lost also

September 15, 2015 - 8:38pm #27

I found that there is no need to declare mContentManager variable into  'CloudRecoEventHandler.cs' and it will solve duplicated object appearing.

gameobject visible on tracking lost also

July 17, 2014 - 9:33am #26

Happy to help!

gameobject visible on tracking lost also

July 17, 2014 - 9:29am #25

Done and it works like a charm, cheers to you!

gameobject visible on tracking lost also

July 17, 2014 - 9:23am #24

Good to know!

Comment it out. I had initially used it when I was not destroying the gameobject. And made a lot of revisions after that. Anyhow, remove it, it is not required (as far as I can remember now ;) It has been a long time since I opened this project now).

Cheers!

gameobject visible on tracking lost also

July 17, 2014 - 9:11am #23

Found why. :)

It was because of this (I commented out the part that was causing troubles):

		if(firsttimeShow)
		{
			//mContentManager.OnTrackingFound();
			firsttimeShow = false;
		}

Is there a particular reason for that bit of code? Or can I take it out (including the bool) as it doesn't seem to be used for anything else.

gameobject visible on tracking lost also

July 17, 2014 - 9:01am #22

No, I gave up on adapting your code to mine and copied/pasted your code entirly and then added some bits of my code. But the LoadBundle function is not there anymore as my SimpleCloudRecoEventHandler is the exact same as your CloudRecoEventHandler. 

I think I'm good to spend the coming hours commenting out different parts of my code to see where that comes from haha!

I'll let you know if I find a solution, or if I don't too...

 

Thanks for your help. ;)

gameobject visible on tracking lost also

July 17, 2014 - 8:57am #21

Hmm...looks strange..

Perhaps, in your script SimpleCloudRecoEventHandler function, OnNewSearchResult, you have called a coroutine, LoadBundle! Comment that out. This might be the problem.

gameobject visible on tracking lost also

July 17, 2014 - 8:46am #20

Yup, there you go :)

AttachmentSize
Image icon screenshot_Unity.png53.01 KB

gameobject visible on tracking lost also

July 17, 2014 - 8:41am #19

Cool! :)

Can you upload the screenshot of CloudRecoTarget inspector?

gameobject visible on tracking lost also

July 17, 2014 - 8:35am #18

Ok, this time it's totally my fault, didn't try hard enough! I had to go down to 0.001 to see something appearing on my tracker, sorry and yay!

I still have a small issue though, the first object augmented is augmented twice, and one of them is staying all along on the screen (as before). If I try to augment an other one afterwards and then lose the tracker the other one disappear so... double yay!

Any idea why at the first recognition the object is augmented twice? Can't see anything in the code doing that...

 

Thanks a lot!

gameobject visible on tracking lost also

July 17, 2014 - 8:20am #17

I already tried with the scale problem, I'll try again with higher values just in case.

To be honest, I didn't know a mesh was needed, cause it works quite well with my previous code (without using the AugmentationObject child):

But.... yeah, it stays even when the tracker is not on the camera, not cool. :(

I'm sending you the link by PM. :) I'm using Unity 4.3 though, so I'm not sure it'll work with yours. :/

AttachmentSize
Image icon screenshot_Unity.png395.45 KB
Image icon screenshot_Unity2.png338.89 KB

gameobject visible on tracking lost also

July 17, 2014 - 8:10am #16

There might be one possible solution to this. Change the scale of AugmentationObject to (1,1,1) from inspector and reduce the scale of picasso also. Sometimes the object is too big to come inside the viewport of camera. 

I just had a look at your gameobject, picasso, it doesn't have a mesh on it! How will it render without a mesh?

if you can send me the link to your unity asset bundle ( I am using Unity 4.2.1), I can have a look at it in my project. 

gameobject visible on tracking lost also

July 17, 2014 - 8:02am #15

Wow, that was quick, thanks. :)

So I've edited my code to put the modifications you've made into it and now my object is a child of AugmentationObject, though I still have the same problem, target is recognised, object is augmented.... at least that's what the hierarchy says, cause it's not showing on the scene. :(

Here's the code I'm using, it's slightly different from yours as I'm requiring the Metadata instead of the Targetname and then parsing it to acquire some properties of the object (scale, roatation, position). Can you see anything wrong with it? I think I did right when copying your modifications but an external view is always good to take.

	#region ASSIGN 3D MODEL
	
	//This method downloads asset bundle from server every time and instantiates it
	//you can control it with a mechanism which doesn't download the asset everytime a target image is detected
	IEnumerator assign3DModelCloud(string assetDwnLinkPrefix, string detectedTargetMetadata)
	{
		string[] infos = detectedTargetMetadata.Split(',');
		string name = infos[0];
		float[] properties = new float[11];
		for (int i = 1; i < infos.Length; i++)
		{
			properties[i-1] = Single.Parse(infos[i]);
		}
		#if UNITY_EDITOR
		assetDwnLinkPrefix = "http://www.fr//web/"; 
		#endif
		
		#if UNITY_IPHONE
		assetDwnLinkPrefix = "http://.fr//ios/"; 
		#endif
		
		#if UNITY_ANDROID
		assetDwnLinkPrefix = "http://.fr//android/"; 
		#endif
		//assetDwnLinkPrefix is the download link
		string assetDwnLink = assetDwnLinkPrefix + name + ".unity3d";
		Debug.Log (assetDwnLink);
		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; 
			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]);
			GO.SetActive(true);
			assetBundle.Unload(false);

			Renderer[] rendererComponents = AugmentationObject.GetComponentsInChildren<Renderer>();
			Collider[] colliderComponents = AugmentationObject.GetComponentsInChildren<Collider>();
			
			// Enable rendering:
			foreach (Renderer component in rendererComponents)
			{
				component.enabled = true;
			}
			
			// Enable colliders:
			foreach (Collider component in colliderComponents)
			{
				component.enabled = true;
			}
		}
	}
	#endregion ASSIGN 3D MODEL

Here's another screenshot showing the properties of the object loaded from the server, the metadata is there too, I'll keep looking where the problem can come from but to be honest I start to run out of ideas! :P

Thanks again for your help, really appreciate it!

Edit: Good guy forum who adds a href link on my code cause of the www.assetBundle, it's of course not there :P

AttachmentSize
Image icon screenshot_Unity.png1.14 MB

gameobject visible on tracking lost also

July 17, 2014 - 7:04am #14

Oh! My bad!

There is a mistake in my code, in ContentManager script, method assign3DModelCloud. In the screenshot you shared, your asset is instantiated as a child of CloudRecoTarget. It should be the child of AugmentationObject.

The bug is in this line,

GO.transform.parent = GameObject.Find("CloudRecoTarget").transform;

Replace the assign3DModelCloud function with the below,

//This method downloads asset bundle from server every time and instantiates it
//you can control it with a mechanism which doesn't download the asset everytime a target image is detected
IEnumerator assign3DModelCloud(string assetDwnLinkPrefix, string detectedTargetName)
{
	//assetDwnLinkPrefix is the download link
	string assetDwnLink = assetDwnLinkPrefix + detectedTargetName + ".unity3d";
	
	using(WWW www = new WWW(assetDwnLink))
	{
		yield return www;
		File.WriteAllBytes(Application.persistentDataPath + "/" + detectedTargetName, www.bytes);
    	AssetBundle assetBundle = www.assetBundle;
    	GameObject gameobj = assetBundle.mainAsset as GameObject; 
    	GO = Instantiate(gameobj) as GameObject;
    	GO.transform.parent = GameObject.Find("AugmentationObject").transform;
		GO.SetActive(true);
		assetBundle.Unload(false);
		
		Renderer[] rendererComponents = AugmentationObject.GetComponentsInChildren<Renderer>();
        Collider[] colliderComponents = AugmentationObject.GetComponentsInChildren<Collider>();
		
		// Enable rendering:
		foreach (Renderer component in rendererComponents)
		{
			component.enabled = true;
		}
		
		// Enable colliders:
		foreach (Collider component in colliderComponents)
		{
			component.enabled = true;
		}
	}
}

This will solve the issue :)

gameobject visible on tracking lost also

July 17, 2014 - 6:23am #13

Hi!

Thanks a lot for your input and for sharing your code with me!

So, after trying all day, the closer I can get to have it working is loading my object from the cloud, and seeing it in the hierarchy (while trying to debug with unity), but nothing actually appears on the top of the target in the scene, any idea where that come from? 
Here's a screenshot of how it looks like:

1: You can see my object is loaded there, if I open it in the inspector I see that the textures are loaded well etc. The scale and postition of the object are ok too (based on parsed metadata I get through the image target).

2: No problem while loading the object from my server...

I thought it could also be a problem of BundleAssets made for the wrong device that are then not shown, but I tried on my tablet and it's not working either. Plus i've added this part to make sure it takes the right file on my server:

		#if UNITY_EDITOR
		assetDwnLinkPrefix = "http://www.fr/www/web/"; 
		#endif
		
		#if UNITY_IPHONE
		assetDwnLinkPrefix = "http://www.fr/www/ios/"; 
		#endif
		
		#if UNITY_ANDROID
		assetDwnLinkPrefix = "http://www.fr/www/android/"; 
		#endif

Hope you'll be able to help with that!

AttachmentSize
Image icon screenshot_Unity.png1.09 MB

gameobject visible on tracking lost also

July 16, 2014 - 10:00am #12

Hi Arlem!

I have modified the ContentManager and CloudRecoEventHander scripts for my use. Have a look at the Unity inspector and hierarchy and the scripts below,

Take an empty gameobject and make it (AugmentationObject) a child of your ImageTarget (CloudRecoTarget in my case),

Add ContentManager script on CloudRecoTarget and add the above created gameobject (AugmentationObject) on "Augmentation Object" object in inspector. Keep GO empty, it will be instantiated at runtime when an image target is detected by the downloaded asset bundle,

ContentManager script,

/*==============================================================================
Copyright (c) 2012-2013 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Qualcomm Connected Experiences, Inc.
==============================================================================*/

using UnityEngine;
using System.Collections;
using System.Timers;
using SimpleJSON;
using System.Collections.Generic;
using System.IO;

/// <summary>
/// This class manages the content displayed on top of cloud reco targets in this sample
/// </summary>
public class ContentManager : MonoBehaviour,
								ITrackableEventHandler
{
    #region PUBLIC_VARIABLES
    /// <summary>
    /// The root gameobject that serves as an augmentation for the image targets created by search results
    /// </summary>
    public GameObject GO;
	public GameObject AugmentationObject;
	
	//Asset bundle download link
	public static string assetDwnLink;
	
	string assetDwnLinkPrefix = "a_URL_to_download_asset_bundle";
	#endregion PUBLIC_VARIABLES
	
	#region UNTIY_MONOBEHAVIOUR_METHODS

    void Start ()
    {
		//make AugmentationObject child of CloudRecoTarget
		//and your asset bundle will be gameobject GO (in my case) where you will instantiate it
		TrackableBehaviour trackableBehaviour = AugmentationObject.transform.parent.GetComponent<TrackableBehaviour>();
		
		if (trackableBehaviour)
        {
            trackableBehaviour.RegisterTrackableEventHandler(this);
        }
        
        //ShowObject(false);
		OnTrackingLost();
    }
	
	#endregion UNTIY_MONOBEHAVIOUR_METHODS
	
	
	
    #region PUBLIC_METHODS
    
    /// <summary>
    /// Implementation of the ITrackableEventHandler function called when the
    /// tracking state changes.
    /// </summary>
    public void OnTrackableStateChanged(
                                    TrackableBehaviour.Status previousStatus,
                                    TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED || 
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            //ShowObject(true);
			//Debug.Log ("Detected");
			OnTrackingFound();
        }
        else
        {
            //ShowObject(false);
			OnTrackingLost();
        }
    }
	
	public void OnTrackingFound()
    {
		StartCoroutine(assign3DModelCloud(assetDwnLinkPrefix, CloudRecoEventHandler.detectedTargetName));
		
		Renderer[] rendererComponents = AugmentationObject.GetComponentsInChildren<Renderer>();
        Collider[] colliderComponents = AugmentationObject.GetComponentsInChildren<Collider>();
		
		// Enable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = true;
        }

        // Enable colliders:
        foreach (Collider component in colliderComponents)
        {
            component.enabled = true;
        }
    }

	public void OnTrackingLost()
    {
		if(GO)
		{
			Destroy(GO);
		}
    }
    
	#endregion PUBLIC_METHODS
	
	#region ASSIGN 3D MODEL
	
	//This method downloads asset bundle from server every time and instantiates it
	//you can control it with a mechanism which doesn't download the asset everytime a target image is detected
	IEnumerator assign3DModelCloud(string assetDwnLinkPrefix, string detectedTargetName)
	{
		//assetDwnLinkPrefix is the download link
		string assetDwnLink = assetDwnLinkPrefix + detectedTargetName + ".unity3d";
		
		using(WWW www = new WWW(assetDwnLink))
		{
			yield return www;
			File.WriteAllBytes(Application.persistentDataPath + "/" + detectedTargetName, www.bytes);
        	AssetBundle assetBundle = www.assetBundle;
        	GameObject gameobj = assetBundle.mainAsset as GameObject; 
        	GO = Instantiate(gameobj) as GameObject;
        	GO.transform.parent = GameObject.Find("CloudRecoTarget").transform;
			GO.SetActive(true);
			assetBundle.Unload(false);
		}
   	}
	#endregion ASSIGN 3D MODEL
}

 

In the CloudReco sample, there is a script called CloudRecoEventHandler. I have customized this script a little,

/*==============================================================================
Copyright (c) 2012-2013 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
==============================================================================*/

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.IO;

/// <summary>
/// This MonoBehaviour implements the Cloud Reco Event handling for this sample.
/// It registers itself at the CloudRecoBehaviour and is notified of new search results as well as error messages
/// The current state is visualized and new results are enabled using the TargetFinder API.
/// </summary>
public class CloudRecoEventHandler : MonoBehaviour, ICloudRecoEventHandler
{
    #region PRIVATE_MEMBER_VARIABLES

    // ImageTracker reference to avoid lookups
    private ImageTracker mImageTracker;
    private ContentManager mContentManager;
	//private CloudRecoBehaviour mCloudRecoBehaviour;
	public static CloudRecoBehaviour mCloudRecoBehaviour;
	
	//Image target detected and Asset bundle download link
	public static string detectedTargetName;
	
	//to call ShowObject() only once
	public static bool firsttimeShow;
	
	//The parent gameobject of the referenced ImageTargetTemplate - reused for all target search results
    private GameObject mParentOfImageTargetTemplate;

    #endregion // PRIVATE_MEMBER_VARIABLES



    #region EXPOSED_PUBLIC_VARIABLES

    /// <summary>
    /// can be set in the Unity inspector to reference a ImageTargetBehaviour that is used for augmentations of new cloud reco results.
    /// </summary>
    public ImageTargetBehaviour ImageTargetTemplate;

    #endregion

    #region ICloudRecoEventHandler_IMPLEMENTATION

    /// <summary>
    /// called when TargetFinder has been initialized successfully
    /// </summary>
    public void OnInitialized()
    {
        // get a reference to the Image Tracker, remember it
        mImageTracker = TrackerManager.Instance.GetTracker<ImageTracker>();
        mContentManager = (ContentManager)FindObjectOfType(typeof(ContentManager));
    }

    /// <summary>
    /// visualize initialization errors
    /// </summary>
    public void OnInitError(TargetFinder.InitState initError)
    {
        switch (initError)
        {
            case TargetFinder.InitState.INIT_ERROR_NO_NETWORK_CONNECTION:
                ErrorMsg.New("Network Unavailable", "Please check your internet connection and try again.", RestartApplication);
                break;
            case TargetFinder.InitState.INIT_ERROR_SERVICE_NOT_AVAILABLE:
                ErrorMsg.New("Service Unavailable", "Failed to initialize app because the service is not available.");
                break;
        }
    }
    
    /// <summary>
    /// visualize update errors
    /// </summary>
    public void OnUpdateError(TargetFinder.UpdateState updateError)
    {
        switch (updateError)
        {
            case TargetFinder.UpdateState.UPDATE_ERROR_AUTHORIZATION_FAILED:
                ErrorMsg.New("Authorization Error","The cloud recognition service access keys are incorrect or have expired.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_NO_NETWORK_CONNECTION:
                ErrorMsg.New("Network Unavailable","Please check your internet connection and try again.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_PROJECT_SUSPENDED:
                ErrorMsg.New("Authorization Error","The cloud recognition service has been suspended.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_REQUEST_TIMEOUT:
                ErrorMsg.New("Request Timeout","The network request has timed out, please check your internet connection and try again.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_SERVICE_NOT_AVAILABLE:
                ErrorMsg.New("Service Unavailable","The service is unavailable, please try again later.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_TIMESTAMP_OUT_OF_RANGE:
                ErrorMsg.New("Clock Sync Error","Please update the date and time and try again.");
                break;
            case TargetFinder.UpdateState.UPDATE_ERROR_UPDATE_SDK:
                ErrorMsg.New("Unsupported Version","The application is using an unsupported version of Vuforia.");
                break;
        }
    }

    /// <summary>
    /// when we start scanning, unregister Trackable from the ImageTargetTemplate, then delete all trackables
    /// </summary>
    public void OnStateChanged(bool scanning)
    {
        if (scanning)
        {
			// clear all known trackables
            mImageTracker.TargetFinder.ClearTrackables(false);

            // hide the ImageTargetTemplate
            mContentManager.OnTrackingLost();
        }
    }
    
    /// <summary>
    /// Handles new search results
    /// </summary>
    /// <param name="targetSearchResult"></param>
	public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)
    {
        // First clear all trackables
        mImageTracker.TargetFinder.ClearTrackables(false);
		
		//Tracking found via CLOUD, ContentManager.OnTrackingFound function is called
		detectedTargetName = targetSearchResult.TargetName;
		
		if(firsttimeShow)
		{
			mContentManager.OnTrackingFound();
			firsttimeShow = false;
		}
		
        // enable the new result with the same ImageTargetBehaviour:
        ImageTargetBehaviour imageTargetBehaviour = mImageTracker.TargetFinder.EnableTracking(targetSearchResult, mParentOfImageTargetTemplate) as ImageTargetBehaviour;
    }
	
	#endregion // ICloudRecoEventHandler_IMPLEMENTATION



    #region UNTIY_MONOBEHAVIOUR_METHODS

    /// <summary>
    /// register for events at the CloudRecoBehaviour
    /// </summary>
    void Start()
    {
		firsttimeShow = true;
		// look up the gameobject containing the ImageTargetTemplate:
        mParentOfImageTargetTemplate = ImageTargetTemplate.gameObject;

        // intialize the ErrorMsg class
        ErrorMsg.Init();

        // register this event handler at the cloud reco behaviour
        CloudRecoBehaviour cloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();
        if (cloudRecoBehaviour)
        {
            cloudRecoBehaviour.RegisterEventHandler(this);
        }
		
		// remember cloudRecoBehaviour for later
        mCloudRecoBehaviour = cloudRecoBehaviour;
    }

    #endregion UNTIY_MONOBEHAVIOUR_METHODS

    #region PRIVATE_METHODS
    
    // callback for network-not-available error message
    private void RestartApplication()
    {
        //Application.LoadLevel("Vuforia-1-About");
    }
    #endregion PRIVATE_METHODS
}

 

Hope, this solves your problem.

Cheers!

AttachmentSize
Image icon hierarchy.jpg15.71 KB
Image icon augObj.jpg96.95 KB

gameobject visible on tracking lost also

July 16, 2014 - 12:51am #11

Hi,

 

I'm still looking but can't find a way to solve that...

No one know a way around this problem? Anyone from the Vuforia team maybe?

 

gameobject visible on tracking lost also

July 11, 2014 - 9:26am #10

Or if anyone else has a solution, I'm listening. :)

I already tried to use OnStageChanged() (from the SimpleCloudRecoEventHandler) or OnTrackableStateChanged() (from the DefaultTrackableEventHandler) but without any success. 

My augmented object is stored in a GameObject variable so my first thought was to do something like this:

void Update()
{
   if(temp_gameobject !=null && !TargetDetected())
   {
      temp_gameobject == null
   }
}

The first part of the condition works but I don't know what else to put instead of the TargetDetected() (meant to be a method returning true if the target is seen, false if not). 

Here is my full SimpleCloudRecoEventHandler.cs script (slightly different from the original) if that can help:
 


/*==============================================================================
Copyright (c) 2012 QUALCOMM Austria Research Center GmbH.
All Rights Reserved.
Qualcomm Confidential and Proprietary
==============================================================================*/

using System;
using UnityEngine;
using System.Collections;
using System.Collections.Generic;

/// <summary>
/// This MonoBehaviour implements the Cloud Reco Event handling for this sample.
/// It registers itself at the CloudRecoBehaviour and is notified of new search results.
/// </summary>
public class SimpleCloudRecoEventHandler : MonoBehaviour, ICloudRecoEventHandler
{
	#region PRIVATE_MEMBER_VARIABLES
	
	// CloudRecoBehaviour reference to avoid lookups
	private CloudRecoBehaviour mCloudRecoBehaviour;
	// ImageTracker reference to avoid lookups
	private ImageTracker mImageTracker;
	
	private GameObject obj, obj_temp;

	private WWW www;
	private string BundleURL;

	#endregion // PRIVATE_MEMBER_VARIABLES
	
	
	
	#region EXPOSED_PUBLIC_VARIABLES
	
	/// <summary>
	/// can be set in the Unity inspector to reference a ImageTargetBehaviour that is used for augmentations of new cloud reco results.
	/// </summary>
	public ImageTargetBehaviour ImageTargetTemplate;
	
	#endregion
	
	#region UNTIY_MONOBEHAVIOUR_METHODS
	
	/// <summary>
	/// register for events at the CloudRecoBehaviour
	/// </summary>
	void Start()
	{
		// register this event handler at the cloud reco behaviour
		CloudRecoBehaviour cloudRecoBehaviour = GetComponent<CloudRecoBehaviour>();
		if (cloudRecoBehaviour)
		{
			cloudRecoBehaviour.RegisterEventHandler(this);
		}
		// remember cloudRecoBehaviour for later
		mCloudRecoBehaviour = cloudRecoBehaviour;
		
	}

	#endregion // UNTIY_MONOBEHAVIOUR_METHODS
	
	
	#region ICloudRecoEventHandler_IMPLEMENTATION
	
	/// <summary>
	/// called when TargetFinder has been initialized successfully
	/// </summary>
	public void OnInitialized()
	{
		// get a reference to the Image Tracker, remember it
		mImageTracker = TrackerManager.Instance.GetTracker<ImageTracker>();
	}
	
	/// <summary>
	/// visualize initialization errors
	/// </summary>
	public void OnInitError(TargetFinder.InitState initError)
	{
	}
	
	/// <summary>
	/// visualize update errors
	/// </summary>
	public void OnUpdateError(TargetFinder.UpdateState updateError)
	{
	}
	
	/// <summary>
	/// when we start scanning, unregister Trackable from the ImageTargetTemplate, then delete all trackables
	/// </summary>
	public void OnStateChanged(bool scanning)
	{
		if(scanning && obj_temp != null)
		{
			Hide(obj_temp);
		}
	}
	
	/// <summary>
	/// Handles new search results
	/// </summary>
	/// <param name="targetSearchResult"></param>

	public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)
	{
		// duplicate the referenced image target
		GameObject newImageTarget = Instantiate(ImageTargetTemplate.gameObject) as GameObject;         
		GameObject augmentation = null; 
		mCloudRecoBehaviour.CloudRecoEnabled = true;
		//// CHANGING model_name TO AN EXPECTED URL, CALLED LATER BELOW   
		#if UNITY_EDITOR
		BundleURL = "http://URL_SERVER/models_WEB.unity3d"; 
		#endif
		
		#if UNITY_IPHONE
		BundleURL = "http://URL_SERVER/models_IOS.unity3d"; 
		#endif
		
		#if UNITY_ANDROID
		BundleURL = "http://URL_SERVER/models_ANDROID.unity3d"; 
		#endif

		string model_infos = targetSearchResult.MetaData;
		string[] infos = model_infos.Split(',');
		string name = infos[0];
		float[] properties = new float[11];
		for (int i = 1; i < infos.Length; i++)
		{
			properties[i-1] = Single.Parse(infos[i]);
		}
		StartCoroutine(LoadBundle(BundleURL, name, properties));
		if( augmentation != null )
			augmentation.transform.parent = newImageTarget.transform; 
		// enable the new result with the same ImageTargetBehaviour:
		ImageTargetBehaviour imageTargetBehaviour = (ImageTargetBehaviour)mImageTracker.TargetFinder.EnableTracking(targetSearchResult, newImageTarget);         
	}

	IEnumerator LoadBundle(string BundleURL, string name, float [] properties)
	{		

		// Start a download of the given URL
		www = WWW.LoadFromCacheOrDownload (BundleURL, 1);
		// Wait for download to complete
		yield return www;
		
		// Load and retrieve the AssetBundle
		AssetBundle bundle = www.assetBundle;

		// Load the object asynchronously
		AssetBundleRequest request = bundle.LoadAsync (name, typeof(GameObject));
		// Wait for completion
		yield return request;
		// Get the reference to the loaded object
		obj = request.asset as GameObject;
		obj.transform.localPosition = new Vector3(properties[0], properties[1], properties[2]);
		obj.transform.eulerAngles  = new Vector3(properties[3], properties[4], properties[5]);
		obj.transform.localScale = new Vector3(properties[6], properties[7], properties[8]);
		if (www == null)
			throw new Exception("WWW download had an error:" + "sacre error");
		else
			obj_temp = Instantiate(obj) as GameObject;

		bundle.Unload(false);
	}

#endregion // ICloudRecoEventHandler_IMPLEMENTATION
	
	private void Hide( GameObject model ){
		
		Debug.Log( "Hiding "+ model.name );

		model.SetActive(false);
		
		Renderer[] rendererComponents = model.GetComponentsInChildren<Renderer>();
		Collider[] colliderComponents = model.GetComponentsInChildren<Collider>();
		
		// Disable rendering:
		foreach (Renderer component in rendererComponents)
		{
			component.enabled = false;
		}
		
		// Disable colliders:
		foreach (Collider component in colliderComponents)
		{
			component.enabled = false;
		}
	}

}

Thanks a lot to anyone that is willing to help me!

gameobject visible on tracking lost also

July 10, 2014 - 9:14am #9

Hi Jainam,

 

I know that thread starts to get old but hopefully you'll get my question!

I'm currently facing the same problem, I'm using cloud recognition and augmenting the objects via a server. The augmentation works fine but when I lost the tracking the object stays on the screen. 

I did try to understand how you solved this but can't really understand it and, obviously, can't make it work... Could you please explain a bit more how you managed to do it? 

 

Thanks!

gameobject visible on tracking lost also

February 5, 2014 - 12:16am #8

Good to hear!

gameobject visible on tracking lost also

February 4, 2014 - 8:46pm #7

Thanks Alessandro!

Your previous answer helped me crossing the hurdle. I got it working with my own code, played a trick of creating an empty gameobject and making it the child of "CloudRecoTarget". Then linked it to TrackableBehaviour in Start method of "ContentManager" script.

gameobject visible on tracking lost also

February 4, 2014 - 2:01am #6

Have a look at this tutorial:

https://developer.vuforia.com/forum/faq/unity-how-can-i-augment-my-image-target-model

This shows how to augment using Asset Bundles; then, all you need to do is to implement the OnTrackableStateChanged() method and the  OnTrackingLost() method called from the OnTrackableStateChanged(), which you can copy from the DefaultTrackableEventHandler.

It should be quite straightforward to do.

 

 

 

gameobject visible on tracking lost also

February 4, 2014 - 1:48am #5

The problem with my code is that as the assetbundle is getting downloaded at runtime I can't attach it to the TrackableBehaviour. Below is the Start() method from sample (v2.8.9),

void Start ()
    {

        TrackableBehaviour trackableBehaviour = AugmentationObject.transform.parent.GetComponent<TrackableBehaviour>();
		if (trackableBehaviour)
        {
            trackableBehaviour.RegisterTrackableEventHandler(this);
        }
        
        ShowObject(false);
    }

where, "AugmentationObject" is the teapot. But in my case, there is not gameobject to transform to...

void Start ()
    {
		TrackableBehaviour trackableBehaviour = GetComponent<TrackableBehaviour>();
		
		if (trackableBehaviour)
        {
            trackableBehaviour.RegisterTrackableEventHandler(this);
        }
        
        ShowObject(false);
    }

The DefaultEventHandler script also doesn't have any gameobject attached to the TrackableBehaviour.

I am stuck with this problem since Saturday..... it would be great if you could have a look at my scripts and suggest something.

Thanks in advance!

gameobject visible on tracking lost also

February 4, 2014 - 12:22am #4

The OnTrackingLost() function in DefaultTrackableEventHandler is called automatically whenever the target is lost, i.e. the Vuforia engine takes care of calling it;

if you look at the code in DefaultTrackableEventHandler, in the Start() method you will see that the handler is registered with the trackable; once registered, the OnTrackingLost will be called whenever needed. So, you really need to start from that script..

 

gameobject visible on tracking lost also

February 3, 2014 - 8:29pm #3

Hi @Alessandro!

Thanks for your reply. In the below "dummyContentManager" script there is a function "ShowObject(bool tf)" which does the same as "OnTrackingLost" (same as in SDK 2.6.7 samples). I am not able to figure out how to turn this boolean "tf" to false on tracking lost? I mean, even if I use "OnTrackingFound" and "OnTrackingLost" from the old scripts, how will I trigger "OnTrackingLost" function?

Thanks!

gameobject visible on tracking lost also

February 3, 2014 - 6:47am #2

The CloudRecoEventHandler - OnStateChanged() simply notifies you if the scanning is ON or OFF; but this is not sufficient for hidign the model when it gets lost;   for that, you need to use a custom version of ITrackableEventHandler, taking inspiration from the DefaultTrackableEventHandler, which is also used in most of the samples.

In particular, the DefaultTrackableEventHandler contains a method called OnTrackingLost() to achieve this.

 

 

Log in or register to post comments