Log in or register to post comments

Replace teapot with a 3D model using Unity

April 18, 2013 - 8:42am #1

Hi,

I'm implementing an AR application where the user should be able to select which object he wants to be drawn. Since the objects are in FBX format I decided to do it using Unity. I saw there's a tutorial to do change the object using openGL: https://developer.vuforia.com/resources/dev-guide/replacing-teapot, but I couldn't find anything like that about Unity.

I managed to run the ImageTargets example with the teapot, and now I want to be able to dynamically change the object loaded, but I don't know how to do that. I'm really new with Unity, and I'm completely lost. Is it possible to do it using Unity? Where should I start?

Thanks!

Replace teapot with a 3D model using Unity

May 16, 2015 - 1:57pm #23

Hi there,

I'm trying to show 3D models instead of simple cubes on trackables, via the code  below:

 

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
 
 
 
namespace Vuforia
{
[RequireComponent(typeof(MeshRenderer))]
 
public class TrackableList : MonoBehaviour {
 
public Transform  teapot  ;
//public  GameObject  teapot ;
public Material myNewMaterial ;
// Use this for initialization
 
// Update is called once per frame
void Update () {
// Get the StateManager
StateManager sm = TrackerManager.Instance.GetStateManager ();
 
 
 
// Query the StateManager to retrieve the list of
// currently 'active' trackables 
//(i.e. the ones currently being tracked by Vuforia)
IEnumerable<TrackableBehaviour> activeTrackables = sm.GetActiveTrackableBehaviours ();
foreach (TrackableBehaviour tb in activeTrackables) {
string trackableName = tb.TrackableName;
if(trackableName != null)
{
 
Transform myModel = GameObject.Instantiate(teapot) as Transform;
 
 
 
myModel.transform.parent = tb.transform;
myModel.transform.localScale = new Vector3(3.0f, 3.0f, 3.0f);
myModel.transform.localPosition = new Vector3(0.0f, 0.25f, 0.0f);
myModel.transform.localRotation = Quaternion.identity;
myModel.transform.gameObject.SetActive(true);
 
}} }
}
}
But the teapot doesn't appear at all. What's wrong with this code ? Thank's in advance

Replace teapot with a 3D model using Unity

May 14, 2013 - 10:19pm #22

Great, glad to help!

Replace teapot with a 3D model using Unity

May 14, 2013 - 2:39pm #21

Hi,

I used the code you said with just a little change to avoid an exception:

Transform myModelTrf = GameObject.Instantiate(bundle.Load( AssetName, typeof(Transform) )) as Transform;

 

And I had the same problem I had with code 4: my object is rendered before the target is detected. The good thing is that now I only have 1 instance of the object, not 2 as I had.

To solve the issue that the object is rendered too soon I changed your line:

myModelTrf.gameObject.active = true;

with:

myModelTrf.gameObject.SetActive(false);

 

This way the object is inactive at start . Then, if I find the track (script DefaultTrackableEventHandler), I use SetActive(true) to render it.

Thank you for your help! :)

Replace teapot with a 3D model using Unity

May 14, 2013 - 2:10am #20

Hi, I would sugegst to use the script in this link:

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

In particular, when you instantiate, you should do the following:

 

Transform myModelTrf = GameObject.Instantiate(bundle.Load( AssetName )) as Transform;
 
 myModelTrf.parent = mTransform; //mTransform is the transform of your Image target            
 myModelTrf.localPosition = new Vector3(0f, 0f, 0f);
 myModelTrf.localRotation = Quaternion.identity;
 myModelTrf.localScale = new Vector3(0.0005f, 0.0005f, 0.0005f);
 
 myModelTrf.gameObject.active = true;
 

Replace teapot with a 3D model using Unity

May 13, 2013 - 2:40pm #19

I did some testing and I almost make it work. Now I have two instances of my object, one is never seen and the other one is, but the one that is seen is rendered even if the tracker isn't found. I paste here the the tests I did. The Code 4 is the one that is closer to what I want.

 

Code 1: 

 

GameObject loadedTarget = bundle.Load(slectedItem, typeof(GameObject)) as GameObject;
Instantiate(loadedTarget);
loadedTarget.transform.parent = mTransform.gameObject.transform;
loadedTarget.transform.localPosition = new Vector3(0f, 0f, 0f);
loadedTarget.transform.localScale = new Vector3(10f, 10f, 10f);
 
Result: When I load the model I have 2 object instances: one is a child of ImageTargets and the other one isn't. The instance that is NOT the child of ImageTargets is rendered, but it's really small and its position is not in (0, 0, 0) from the ImageTarget. The object moves when I move the tracker.
 
 
Code 2:
 
GameObject loadedTarget = bundle.Load(slectedItem, typeof(GameObject)) as GameObject;
loadedTarget.transform.parent = mTransform.gameObject.transform;
loadedTarget.transform.localPosition = new Vector3(0f, 0f, 0f);
loadedTarget.transform.localScale = new Vector3(10f, 10f, 10f);

 

Result: When I load the model I have 1 object instance that is a child of ImageTargets. Nothing is seen in screen even if the tracker is found.

 

Code 3:

GameObject loadedTarget = bundle.Load(slectedItem, typeof(GameObject)) as GameObject;
loadedTarget.transform.parent = mTransform.gameObject.transform;
loadedTarget.transform.localPosition = new Vector3(0f, 0f, 0f);
loadedTarget.transform.localScale = new Vector3(10f, 10f, 10f);
Instantiate(loadedTarget);
 
ResultWhen I load the model I have 2 object instances: one is a child of ImageTargets and the other one isn't. The instance that is NOT the child of ImageTargets is rendered with the right scale, but its position is not in (0, 0, 0) from the ImageTarget (obviously, since it's not its child). The object moves when I move the tracker. If then I move the instance in the Hierarchy setting it as a child of ImageTargets and I manually set its position and rotation to (0,0,0) I get the result I want: the object is rendered over the target in (0,0,0).
 

 

 

Code 4:

GameObject loadedTarget = bundle.Load(slectedItem, typeof(GameObject)) as GameObject;
loadedTarget.transform.parent = mTransform.gameObject.transform; 
loadedTarget.transform.localScale = new Vector3(10f, 10f, 10f);
GameObject instance = Instantiate(loadedTarget) as GameObject;
instance.transform.parent = mTransform.gameObject.transform;
instance.transform.localPosition = new Vector3(0f, 0f, 0f);
 

Result: When I select an item (the above code is executed) the object is rendered in screen even if the tracker isn't found. As soon as the tracker is found, the object moves to the right position and scale. If then the tracker is lost, the object disappears.

 
 
With the code 4 I feel that I almost got it, but there's still something wrong. Do you know what am I doing wrong?
 
Thanks!

Replace teapot with a 3D model using Unity

May 12, 2013 - 11:49am #18

Hi,

perhaps you need to adjust the local position and scaling of the object; you could try by adding these lines (after the re-parenting code)

loadedTarget.transform.localPosition = new Vector3(0f, 0f, 0f);

loadedTarget.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f);

 

 

Replace teapot with a 3D model using Unity

May 12, 2013 - 4:58am #17

Hi,

Im' the user who started the thread. I managed to make AssetBundles work (I have it in a server) using a ComboBox to select the models. If I instantiate the objects in a fixed position I can see them on screen, but if I try to associate them with the tracker it's not working.

The script to create the ComboBox, initialize AssetsBundle and load the GameObjects is a component of ImageTarget. To assign the GameObject to the tracker I'm getting ImageTarget's transform and the use the line:

loadedTarget.transform.parent = mTransform.gameObject.transform;

My new GameObject appears as a child of ImageTarget in the Hierarchy, but I can't see it in the screen even if the tracker is found.

 

This is my code:

 

public class ComboBox : MonoBehaviour 
{
    public string[] items;
    public Rect Box;
    public string slectedItem = "None";
 
    private bool editing = false;
 
    private string url = "...";
 
    public AssetBundle bundle;
 
    private Transform mTransform;
 
    IEnumerator Start()
    {
        mTransform = GetComponent<Transform>();
 
        WWW www = WWW.LoadFromCacheOrDownload(url, 1);
 
        yield return www;
 
        bundle = www.assetBundle;
    }
 
    private void OnGUI()
    {
        if (GUI.Button(Box, slectedItem))
        {
            editing = true;
        }
 
        if (editing)
        {
            for (int x = 0; x < items.Length; x++)
            {
                if (GUI.Button(new Rect(Box.x, (Box.height * x) + Box.y + Box.height, Box.width, Box.height), items[x]))
                {
                    slectedItem = items[x];
                    editing = false;
 
                    GameObject loadedTarget = bundle.Load(slectedItem, typeof(GameObject)) as GameObject;
                    Instantiate(loadedTarget);
                    loadedTarget.transform.parent = mTransform.gameObject.transform;
                }
            }
        }
    }
}
 
My Hierarchy is:
-ARCamera
-ImageTarget
 
What am I doing wrong?

Replace teapot with a 3D model using Unity

May 8, 2013 - 1:24am #16

I see. Then you would need to setup a small server on your PC (you could use some free server like apache for instance) and put your assetBundles there.

Then you could connect via the network to your server, using the URL of your server.

This would also represent a "real" use case (as assetBundles are meant to be downloaded from the network anyhow, ...otherwise, if you plan to simply store your assetbundles on your local storage, then you could just import your Models up-front in your Unity project and avoid using AssetBundles...)

 

Replace teapot with a 3D model using Unity

May 8, 2013 - 1:18am #15

Nexus 10 device doesn't have SD card :(

Replace teapot with a 3D model using Unity

May 8, 2013 - 1:16am #14

So, if you want to test loading of AssetBundles from device storage, my suggestion would be to:

  • store the asset bundles into the SDcard of your device (i.e. under /mnt/sdcard/)
  • use this URL: "file:///mnt/sdcard/models.unity3d"

Replace teapot with a 3D model using Unity

May 8, 2013 - 12:40am #13

It might be the path! Thanks a lot! Because I am working with local files by the moment.

So, I copied my models.unity3d file on my android device, but I don't know which is exactly the route. For example:
file:// [...] /Downloads/models.unity3d

On my PC is [Computer\Nexus 10\Internal storage\Download] so it should work with file://Internal storage/Downloads/models.unity3d???

Replace teapot with a 3D model using Unity

May 8, 2013 - 12:14am #12

Ok. If you are absolutely sure that you built your AssetBundles using the BuildTarget.Android (and if the models appear in PlayMode on PC), then there are good chances that the problem is one of the following:

  • the path (URL) to the assetBundle is incorrect when working from tablet (what path are you using? is it pointing to a server on the network or to a file location ?)
  • or, the models are too heavy (too large number of polygons) for being handled on your mobile

 

 

Replace teapot with a 3D model using Unity

May 7, 2013 - 11:56pm #11

That specific model is preattached.

I have a Box 3Dmodel preattached to the Image target.

Then I have an assetbundle with a car and a hanger. Those are loaded and seen when required when I run  my app on the PC. However, when I run it on my tablet, only the box which was preattached (it was NOT on the assetbundle) is seen.

The car and hanger are children of the ImageTarget.

Replace teapot with a 3D model using Unity

May 7, 2013 - 11:53pm #10

Hi, when you say "but the one loaded by default out of the assetBundle", do you mean that that specific model is also loaded from the AssetBundle at runtime, or is it a copy of the model and you pre-attach it to the target ?

 

Replace teapot with a 3D model using Unity

May 7, 2013 - 11:44pm #9

Thank you for for help.

I specified it but it still doesn't work.

No new models are shown but the one loaded by default out of the assetBundle when the app is loaded on my Android device.

Any idea else? Thanks

Replace teapot with a 3D model using Unity

May 7, 2013 - 11:43pm #8

Thank you for for help.

I specified it but it still doesn't work.

No new models are shown but the one loaded by default out of the assetBundle when the app is loaded on my Android device.

Any idea else? Thanks

Replace teapot with a 3D model using Unity

May 7, 2013 - 8:39am #7

Hi Claudia,

when building an AssetBundle, you need to pay attention to the target platform you build it for:

if you need to load and use the AssetBundle from a mobile App on Android, then you will have to build the AssetBundle specifying the Android platform, i.e.:

 

BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets | BuildTarget.Android);

If you plan to use it for iOS, you will need to build the AssetBundle for iOS, i.e:

 

BuildPipeline.BuildAssetBundle(Selection.activeObject, selection, path, BuildAssetBundleOptions.CollectDependencies | BuildAssetBundleOptions.CompleteAssets  | BuildTarget.iPhone);

AssetBundles that have been built for the default (PC) platform will usually not workj with Android or iOS.

I hope this helps.

Replace teapot with a 3D model using Unity

May 7, 2013 - 7:46am #6

Hey!

If you have Pro License, AssetBundles is the key!

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

I am working in a similar app. I have a unity project with vuforia. I have three .fbx models which are in one asset bundle. So when I run the app I can switch which model I can see over the ImageTarget.

I have several buttons that apply diferent transformations over the model.

The thing is that on the emulator everything works perfect, but then when I run it on the tablet no model seems to switch. Any suggestion?

Cheers,

Claudia.

Replace teapot with a 3D model using Unity

April 28, 2013 - 4:54am #5

Sorry for not answering until now, I left this project aside for a while since I had other priorities.

I was thinking on using a ComboBox or something like that to change the model used.

I'm using the ImageTargets example as a base. I've been looking at its scripts and I'm completely lost. I've seen there are two scripts folders: Assets->Scripts and Assets->Qualcomm Augmented Reality->Scripts. In which one should I place my script to be able to access the Trackable Behaviour? I've been looking for mTrackableBehaviour and I can't find it, but I found   ImageTracker mImageTracker,   I don't know if it's that or not.

As you can see I'm kinda lost with all those scripts, if you could recommend me any guide or tutorial it would be really useful for me :)

Thanks!

Replace teapot with a 3D model using Unity

April 18, 2013 - 11:49am #4

To change which model is associated w/ a target, simply define the ImageTarget instance as the parent of that model's transform - http://docs.unity3d.com/Documentation/ScriptReference/Transform-parent.html

You can obtain the GameObject for a target from its Trackable Behaviour..

e.g.

mTrackableBehaviour.gameObject.transform

 

So to make MyModel a child of mTrackableBehaviour, use..

 

MyModel.transform.parent = mTrackableBehaviour.gameObject.transform

 

How do you intend to select which model to use?

 

Replace teapot with a 3D model using Unity

April 18, 2013 - 10:58am #3

Doing it the way you said I can change the object in build time, so the object is directly related to the track. Everytime the camera identifies the track it will load the same object. I want to be able to change the object loaded in runtime. I know that, if it's possible, I'll have to change some of the scripts (I'm a programmer, that's not a problem), but I can't find which ones should I change.

Replace teapot with a 3D model using Unity

April 18, 2013 - 9:47am #2

Hi, in general you can import a 3D model by simply copy the file into the Assets directory under your Unity project directory;

Unity should be able to realize that there is a new model in the Assets directory and will show it in the Project view;

then you can drag the model to your scene and attach it as a child of one of the ImageTargets (instead of the teapot);

however, for more details, I recommend you read this page (from the Unity website):

http://docs.unity3d.com/Documentation/Manual/HOWTO-ImportObjectMax.html

 

Log in or register to post comments