Log in or register to post comments

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 3:28am #1

Hello everybody!

I have some problem in Unity when I want to modify a GameObject.

Indeed, I use the transform property to modify scale or rotation for example, and nothing happens.

Previously, I was using the Device Database from the Target Manager for my image targets, I'm now using the cloud database, so consequently I'm using the Cloud Recognition.

Moreover, I was importing my 3D models with prefabs allready present in my application. Now I'm importing 3D models from a web server with Asset Bundles.

I have added some buttons in the Android part for scaling and rotating the 3D model.

The problem is that in my first app buttonw was working perfectly, but now with asset bundles and cloud recognition they don't work.

 

I explain how I'm doing:

In my Unity scene, I have an AR camera, a CloudRecognition and a CloudRecoTarget.

In the Android part I'm asking to Unity to add a GameObject:

QCARUnityPlayer.UnitySendMessage("CloudRecoTarget", "addObject", pathBat);

And I'm saying to Unity targets name:

QCARUnityPlayer.UnitySendMessage("CloudRecognition", "addImage", pathImage);

 

My function "addObject()" is the next:

public IEnumerator addObject( string path ) {
		
		if(batiment) {
			Debug.Log( "Batiment found!" );
			Destroy( batiment );
		}
		
		//Load obj with Bundle (server)
		WWW www = new WWW( url + path + ".unity3d" );
		
		yield return www;
		
		if( www.isDone ) {
			
			/*AssetBundle*/ bundle = www.assetBundle;
							
			batiment = (GameObject) Instantiate( bundle.Load( path, typeof(GameObject)) );
			batiment.name = "Batiment";
			
			
			if(batiment == null) {
	    	
				Debug.Log("Bundle.Load: obj not found");
	    	
			} else {
				
				Debug.Log("Bundle.Load: obj found");
				
				batiment.transform.localScale = new Vector3(500.0f,500.0f,500.0f);
				batiment.transform.position = new Vector3(0.0f,0.0f,0.0f);
				batiment.transform.parent = this.transform;
				
				Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
		        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
		
		        // Disable rendering:
		        foreach (Renderer component in rendererComponents)
		        {
		            component.enabled = false;
		        }
		
		        // Disable colliders:
		        foreach (Collider component in colliderComponents)
		        {
		            component.enabled = false;
		        }
	
					
			}
			
			bundle.Unload(false);
		
			// Frees the memory from the web stream
			www.Dispose();
		} 
	
	}

This works fine, my 3D model appears when the camera detects the target specified!

What it doesn't work is my buttons, the one which let to turn use the next function:

public void turnObject( string direction ) {
	
		if(batiment) {
			if( direction == "left" ){
				Debug.Log("BATIMENT TURN LEFT : " + batiment.transform.rotation);
	        	        batiment.transform.Rotate(Vector3.up * (-1) * 1.0f);
				batiment.transform.parent = this.transform;
	       	} else if( direction == "right" ){
				Debug.Log("BATIMENT TURN RIGHT : " + batiment.transform.rotation);
				batiment.transform.Rotate(Vector3.up * 1.0f);
				batiment.transform.parent = this.transform;
			}
		}

	}

Log appears when it is executed and rotation is well changed.

But I can't see any change on my screen, the 3D model doesn't move, and I don't understand why...

If someone could help that will be great!

Thank you for your answers!!!

Unity + Vuforia + cloud recognition + modify gameobject

September 5, 2013 - 3:23am #24

Thank you!

I will try this.

I have an other EventHandler. I have a SimpleCloudRecoEventHandler on the CloudRecognition and the DefaultTrackableEventHandler on the CloudRecoTarget. Maybe that's a problem...

Unity + Vuforia + cloud recognition + modify gameobject

September 5, 2013 - 2:51am #23

Nothing obviously wrong, in what I see in your code; 

my suggestion is to try and debug the problem by:

- see if the same problem occurs when you use a simple 3D model not imported from AssetBundles;

- try to log the name of the GameObjects associated to each rendering/collider component that are retrieed by the GetComponentInChildren 

- try to use the component.enable/disable appraoch on the child of the "empty" gameObject (i.e. at the root of your actual 3D Models)

- check if there are other ITrackableEventHandler scripts in your project that may conflict / interfere.

I believe that if you dig carefully with Debug.Logs you should be able to locate the problem.

 

Unity + Vuforia + cloud recognition + modify gameobject

September 5, 2013 - 2:30am #22

Do you think I have done something wrong? 

Sorry if I post a message again but that's maybe one month now that I don't find the solution of my problem...

I thank you for your answers, you are very nice!

Unity + Vuforia + cloud recognition + modify gameobject

September 4, 2013 - 3:22am #21

I have tried and now nothing appeared, that's as if the model wasn't found, here is my log error:

 

"09-04 12:17:02.901: I/Unity(32593): NullReferenceException: Object reference not set to an instance of an object
09-04 12:17:02.901: I/Unity(32593):   at DefaultTrackableEventHandler+<addObject>c__Iterator0.MoveNext () [0x00000] in <filename unknown>:0"
 
And here is the code I have done for tracking:
 
private void OnTrackingFound()
    {
		Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
		
		GameObject.Find("Model").SetActive(true);
		
        Renderer[] rendererComponents = GameObject.Find("Model").GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GameObject.Find("Model").GetComponentsInChildren<Collider>(true);
		
        // Enable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = true;
        }

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

	
    private void OnTrackingLost()
    {
		Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
		
		GameObject.Find("Model").SetActive(false);
		
		Renderer[] rendererComponents = GameObject.Find("Model").GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GameObject.Find("Model").GetComponentsInChildren<Collider>(true);
		
        // Disable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = false;
        }

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

    }

Model refers to the GameObject under the empty GameObject.

And finally here is the code for adding my model:

public IEnumerator addObject( string path ) {
				
		if(batiment) {
			Debug.Log( "Batiment found!" );
			Destroy( batiment );
		}
		
		//Load obj with Bundle (server)
		WWW www = new WWW( url + path + ".unity3d" );
		
		yield return www;
		
		if( www. isDone ) {
			
			AssetBundle bundle = www. assetBundle;
						
			parent.transform.position = new Vector3(0.0f,0.0f,0.0f);
			parent.name = "Batiment";
			
			batiment = (GameObject ) Instantiate( bundle.Load( path, typeof(GameObject )), parent.transform.position, parent.transform.rotation );
			batiment.name = "Model";
			
			if(batiment == null) {
	    	
				Debug.Log("Bundle.Load: obj not found");
	    	
			} else {
				
				Debug.Log("Bundle.Load: obj found");
				
				batiment.transform.parent = parent.transform;
				batiment.transform.localScale = new Vector3(500.0f,500.0f,500.0f);				
				
				GameObject.Find("Model").SetActive(false);
				
				Renderer[] rendererComponents = GameObject.Find("Model").GetComponentsInChildren<Renderer>(true);
		        Collider[] colliderComponents = GameObject.Find("Model").GetComponentsInChildren<Collider>(true);
		
		        // Disable rendering:
		        foreach (Renderer component in rendererComponents)
		        {
		            component.enabled = false;
		        }
		
		        // Disable colliders:
		        foreach (Collider component in colliderComponents)
		        {
		            component.enabled = false;
		        }
				
			}
			
			bundle.Unload(false);
		
			// Frees the memory from the web stream
			www.Dispose();
		}
	
	}

 

 

Unity + Vuforia + cloud recognition + modify gameobject

September 4, 2013 - 2:14am #20

Could you try both methods (component.enabled = false, as well as SetActive(false))  on the GameObject which you have located under the empty game Object ?

This should work.

Unity + Vuforia + cloud recognition + modify gameobject

September 4, 2013 - 12:54am #19

Thank you for your answer again!

I have logged components returned by GetComponentsInChildren, and there is nothing, that explains the problem.

So I've tried like you suggested to use SetActive(false), that changes nothing, but maybe i don't use it in the correct way.

I have tested to use it on the empty object and on the 3Dmodel, I set it to false when I lost my target, and I set it to true when I found my target.

Have I done something wrong?

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 1:11pm #18

Have you tried Logging the component returned by GetComponentsInChildren ?

Also,an alternative approach could be to use SetActive(false) or SetActiveRecursively(false) on your gameObject, see:

http://docs.unity3d.com/Documentation/ScriptReference/GameObject.SetActive.html

 

 

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 7:11am #17

Yes I see the Log messages, tracking is well detected, but 3D models stay on screen, it's like "component.enabled = false" doesn't work ...

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 7:02am #16

Glad to hear the first problem is solved.

do you see the Log messages ("Trackable found", or "Trackable lost") that tels whether the OnTrackingLost/Found are called ?

 

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 6:08am #15

The modification works well with creating an empty object, thank you!!

But now my object is shown even if the target is not detected. The tracking is good but that's as if OnTracking found and OnTracking Lost don't work.

private void OnTrackingFound()
    {
        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;
        }

        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
    }

	
    private void OnTrackingLost()
    {
        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

        // Disable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = false;
        }

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

        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
    }

Maybe that's due to the extra parent?

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 5:06am #14

Hum no, but that sounds good!

I will try this and tell you the result.

Thank you again for your help!

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 5:02am #13

I see ... sounds like an application-level issue or Unity-specific, ..

have you tried adding an empty game object between the target and the AssetBundle ? (i.e. adding an extra parent in the transformation hierarchy) ?

 

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 3:15am #12

That works with the Image Target sample, so I thank you're right there is a problem in the implementation of my DefaultTrackableEventHandler.

The localScale of my target is 1000, so that's good, the problem is not I can't see my 3D model but I can't modify its local transformation like scale or rotation.

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 2:43am #11

Ok. What if you just try with the Image Targets sample and attach the 3D model to the chips (or Stones) targte ?

You can also consult this article:

https://developer.vuforia.com/forum/faq/unity-how-can-i-dynamically-attach-my-3d-model-image-target

If that works, then this would tell there is something wrong in your DefaultTrackableEventHandler implementation with the Cloud Target.

 

Also, another thing to try is to play with the localScale, as you now set it to 500, but perhaps this is too small or too big when compared to the target size.. ?

 

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 2:36am #10

I have tried a simple Unity project and it works really fine, even with instancing asset bundle as gameobject and not transform.

My asset bundle are well built for an Android project.

So I don't think the problem comes from Asset Bundle but maybe from Cloud recognition or the structure of my scene.

Indeed, I have an ARCamera, a CloudRecognition and a CloudRecoTarget. The function for adding 3D models is in the DefaultTrackableEventHandler of the CloudRecoTarget, and the function for turn or zoom on my models are in the same script.

Maybe I've done something wrong.

Unity + Vuforia + cloud recognition + modify gameobject

September 3, 2013 - 12:15am #9

Thank you for your answer, I will try to create a simple Unity project without Vuforia as you said!

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 9:48am #8

In this case I would recommend to try to isolate the problem, by creating a simple Unity project without Vuforia and see whether you can manage to import and display the AssetBundle models in your 3D view (using a standard Unity camera);

this experiment could provide you extra insights on where the problem could be and later you could try to integrate it in your Vuforia project.

Also, one important thing to keep in mind when using AssetBundles is that they need to be built for the Android target, otherwise they will not show up on your device.

See the Unity guide:

http://docs.unity3d.com/Documentation/ScriptReference/BuildPipeline.BuildAssetBundle.html

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

http://docs.unity3d.com/Documentation/ScriptReference/BuildTarget.html

 

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 7:36am #7

Okayn that's what I did, and nothing change.

Here is my code for adding an object:

public IEnumerator addObject( string path ) {
						
		if(batiment) {
			Debug.Log( "Batiment found!" );
			Destroy( batiment );
		}
		
		//Load obj with Bundle (server)
		WWW www = new WWW( url + path + ".unity3d" );
		
		yield return www;
		
		if( www. isDone ) {
						
			AssetBundle bundle = www. assetBundle;
							
			batiment = (Transform ) Instantiate( bundle.Load( path, typeof(Transform )) );
			batiment.name = "Batiment";
			
			
			if(batiment == null) {
	    	
				Debug.Log("Bundle.Load: obj not found");
	    	
			} else {
				
				Debug.Log("Bundle.Load: obj found");
				
				batiment.localScale = new Vector3(500.0f,500.0f,500.0f);
				batiment.position = new Vector3(0.0f,0.0f,0.0f);
				batiment.parent = mTrackableBehaviour.transform;
				
				batiment.gameObject.SetActive(true);
				
				Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
		        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
		
		        // Disable rendering:
		        foreach (Renderer component in rendererComponents)
		        {
		            component.enabled = false;
		        }
		
		        // Disable colliders:
		        foreach (Collider component in colliderComponents)
		        {
		            component.enabled = false;
		        }
	
					
			}
			
			bundle.Unload(false);
		
			// Frees the memory from the web stream
			www.Dispose();
		} 
	
	}

And the code for turn an object:

public void turnObject( string direction ) {
	
		if(batiment) {
			if( direction == "left" ){
				Debug.Log("BATIMENT TURN LEFT : " + batiment.rotation);
	        	batiment.Rotate(Vector3.up * (-1) * 1.0f);
				batiment.parent = this.transform;
	       	} else if( direction == "right" ){
				Debug.Log("BATIMENT TURN RIGHT : " + batiment.rotation);
				batiment.Rotate(Vector3.up * 1.0f);
				batiment.parent = this.transform;
			}
		}
		
	}

Thank you again!

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 7:29am #6

yes.

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 7:18am #5

Thanx !

I'm in the class DefaultTrackableEventHandler which implements MonoBehaviour and ITrackableEventHandler.

I'm not sure but if I do:

batiment.parent = this.transform;

"this" refers to "myTarget" as you said?

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 6:14am #4

You also need to parent the AssetBundle uner one of your Image targets, something like:

batiment.parent = myTarget.transform;

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 5:00am #3

Thank you for your answer!

What you mean is to do something like this?

public IEnumerator addObject( string path ) {
						
		if(batiment) {
			Debug.Log( "Batiment found!" );
			Destroy( batiment );
		}
		
		//Load obj with Bundle (server)
		WWW www = new WWW( url + path + ".unity3d" );
		
		yield return www;
		
		if( www. isDone ) {
			
			AssetBundle bundle = www. assetBundle;
							
			batiment = (Transform ) Instantiate( bundle.Load( path, typeof(Transform )) );
			batiment.name = "Batiment";
			
			
			if(batiment == null) {
	    	
				Debug.Log("Bundle.Load: obj not found");
	    	
			} else {
				
				Debug.Log("Bundle.Load: obj found");
				
				batiment.transform.localScale = new Vector3(500.0f,500.0f,500.0f);
				batiment.transform.position = new Vector3(0.0f,0.0f,0.0f);
				batiment.transform.parent = this.transform;
				
				Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
		        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);
		
		        // Disable rendering:
		        foreach (Renderer component in rendererComponents)
		        {
		            component.enabled = false;
		        }
		
		        // Disable colliders:
		        foreach (Collider component in colliderComponents)
		        {
		            component.enabled = false;
		        }
	
					
			}
			
			bundle.Unload(false);
		
			// Frees the memory from the web stream
			www.Dispose();
		} 
	
	}

I've replaced "GameObject" by "Transform" at line 17.

It's still the same problem, maybe there is other changes to do after this replacement?

Unity + Vuforia + cloud recognition + modify gameobject

September 2, 2013 - 4:12am #2

Hi, the problem seems related to how you instantiate the Assetbundles;

have you tried instantiating them as Transform (instead of GameObject) ?

I recall I had a similar problem in the past, and using Transform did solve it.

 

Log in or register to post comments