"We offer new support options and therefor the forums are now in read-only mode! Please check out our Support Center for more information." - Vuforia Engine Team

gameobject visible on tracking lost also

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!

AlessandroB

Mon, 02/03/2014 - 14:47

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 DefaultTrackableEventHand

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),