Log in or register to post comments

CloudReco and multiple AssetBundles

August 23, 2016 - 3:27am #2

I am trying to associate multiple AssetBundles to a CloudReco, but all my trials so far lead to crash of UnityEditor (total close of unityeditor with webcam that remain locked, so I have to reboot the machine everytime. At least with windows x64) while from the android test application I got this error (The guid is my marker name):

08-23 12:03:45.507  4306  4319 E Unity   : TargetSearchResult a0ad85a1-8882-4aff-9294-165cf166c5b3 could not be enabled for tracking.

Using the demo found here (https://developer.vuforia.com/forum/faq/unity-how-do-i-create-simple-cloud-reco-app) with just one assetbundle everything works, but when I try to implement something less obvious like everything in a coroutine to hanlde multiple assetbundles load, Vuforia crash everytime in the unity editor.

here is the code that give me troubles:

 

    protected void Start()
    {
      var vuforia = FindObjectOfType<VuforiaAbstractBehaviour>();
      if (vuforia != null)
      {
        vuforia.RegisterVuforiaStartedCallback(OnVuforiaStarted);
        vuforia.RegisterOnPauseCallback(OnVuforiaPaused);
      }
      else
        Debug.LogError....

      //Register this event handler at the cloud reco behaviour
      cloudRecoBehaviour = FindObjectOfType<CloudRecoBehaviour>();
      if (cloudRecoBehaviour)
        cloudRecoBehaviour.RegisterEventHandler(this);
    }

    public void OnStateChanged(bool scanning)
    {
      isScanning = scanning;
      if (scanning)
      {
        var tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        tracker.TargetFinder.ClearTrackables(false);
      }
    }

    public void OnNewSearchResult(TargetFinder.TargetSearchResult targetSearchResult)
    {
      var targetMetadata = targetSearchResult.MetaData;
      Debug.Log("Metadata: " + targetMetadata);
      if (string.IsNullOrEmpty(targetMetadata))
        return;
      try
      {
        var models = Newtonsoft.Json.JsonConvert.DeserializeObject<MetadataViewModel[]>(targetMetadata);
        if (models == null)
        {
          Debug.LogError...
          return;
        }
        // stop scanning the cloud
        cloudRecoBehaviour.CloudRecoEnabled = false;
        if (ImageTargetTemplate)
        {
          //Here I delete every child that may exists from previous scans
          CleanObjects(ImageTargetTemplate);
          StartCoroutine(ProcessMetadata(models, targetSearchResult));
        }
      }
      catch (Exception e)
      {
        Debug.LogError...
      }
    }

    private IEnumerator DownloadAndCacheAssetBundle(string pathBase, string fileName, string assetName)
    {
      while (!Caching.ready)
        yield return null;
      var bundleUrl = pathBase.Replace("~/", Constants.DomainUrl) + fileName;
      using (var www = WWW.LoadFromCacheOrDownload(bundleUrl, 0))
      {

        yield return www;
        if (www.error != null)
          throw new Exception("WWW download had an error:" + www.error);
        var bundle = www.assetBundle;
        try
        {
          var obj = bundle.LoadAsset(assetName);
          if (obj != null)
          {
            var asset = Instantiate(obj) as GameObject;
            if (asset != null)
            {
              asset.name = assetName;
              asset.transform.parent = ImageTargetTemplate.transform;
              asset.transform.localPosition = Vector3.zero;
              asset.transform.gameObject.SetActive(false);
              Debug.LogFormat("CloudRecognition: asset loaded \"{0}\" from {1}", assetName, fileName);
            }
          }
          else
            Debug.LogError...
        }
        catch (Exception e)
        {
          Debug.LogError...
        }
        finally
        {
          bundle.Unload(false);
        }
      }
    }

    private IEnumerator ProcessMetadata(MetadataViewModel[] models, TargetFinder.TargetSearchResult targetSearchResult)
    {
      foreach (var model in models)
      {
        switch (model.MetadataType)
        {
          case MetadataType.AssetBundleAndroid:
            //in case I am in UnityEditor my assetbundle are for windows and are loaded without problems
            if (Application.platform == RuntimePlatform.Android || Application.platform == RuntimePlatform.WindowsEditor)
              yield return DownloadAndCacheAssetBundle(model.PathUrl, model.FileName, model.AssetName);
            break;
          case MetadataType.AssetBundleIos:
            if (Application.platform == RuntimePlatform.IPhonePlayer)
              yield return DownloadAndCacheAssetBundle(model.PathUrl, model.FileName, model.AssetName);
            break;
          case MetadataType.Video:

            break;
          case MetadataType.Image:

            break;
        }
      }
      try
      {
        //The code arrive here without problems, I can see in the editor ImageTargetTemplate with 3 different 3d objects loaded and already deactivated
        //I activate the first model
        for (var i = 0; i < ImageTargetTemplate.transform.childCount; i++)
        {
          var obj = ImageTargetTemplate.transform.GetChild(i).gameObject;
          obj.SetActive(i == 0);
          Debug.LogFormat("ProcessMetadata: gameObject: {0}, active:  {1}", obj.name, obj.activeSelf);
        }
      
        var tracker = TrackerManager.Instance.GetTracker<ObjectTracker>();
        if (tracker != null)
          //Here Unity's editor crash, while the android App said that the recognition can not be enabled
          //I also tried to pass a variable containing the active object, but no change in the result
          tracker.TargetFinder.EnableTracking(targetSearchResult, ImageTargetTemplate.gameObject);
        else
          Debug.LogError...
      }
      catch (Exception e)
      {
        Debug.LogError...
      }
    }

Am I missing something obvious?

CloudReco and multiple AssetBundles

August 23, 2016 - 7:55am #1

I solved the problem by calling tracker.TargetFinder.EnableTracking(targetSearchResult, ImageTargetTemplate.gameObject); before starting the corountine e leaving it in the method OnNewSearchResult()

Now I have a similar problem when I call CleanObjects, but I suppose is something  similar. Tghe code is as follow

    private static void CleanObjects(ImageTargetBehaviour imageTargetBehaviour)
    {
      if (imageTargetBehaviour == null)
        return;
      Debug.Log("Pulisco gli oggetti collegati al marker");
      //Svuoto gli eventuali oggetti già associati
      var children = (from Transform child in imageTargetBehaviour.transform select child.gameObject).ToList();
      children.ForEach(Destroy);
    }

Any insight is welcome

Log in or register to post comments