Unity - How can I dynamically attach my 3D model to an Image Target

May 5, 2013 - 8:51am #1

 

This article describes how to augment an image target with a custom 3D model instantiated at runtime, upon target detection, using the Vuforia Unity extension and the Prefab instantiation technique.

For more details about Unity Prefabs, please consult the Prefab guide on the Unity website:

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

Steps:

  • Open/create a Unity project and import the Image targets sample package, and open the image target scene
  • Let’s assume, for ease if reference, that we want to dynamically attach (at runtime) a custom 3D model to the “chips” image target
  • Select the "chips" target and remove the teapot 3D object from the scene, so that the target has no children objects attached underneath
  • In the Project View, under the Assets folder, create a sub-folder called “Prefabs” (if you don’t have one yet)
  • Add a prefab object to the Prefabs folder; there are many ways of creating custom prefabs representing 3D objects; for instance you could create a simple Cube game-object in your scene view and then drag it from the scene view into the Prefabs folder in the Project view; or, you could import a 3D model in a format supported by Unity (such as FBX, OBJ, DAE, 3DS); you can refer to the Unity website for the details on how to create Prefabs from 3D models from various file formats.
  • Create a C# script, call it MyModelInstantiator for instance, and attach it to the “chips” image target object
  • Put the following code into the script and save it:

 

using UnityEngine;
using System.Collections;

public class MyPrefabInstantiator : MonoBehaviour, ITrackableEventHandler {

    private TrackableBehaviour mTrackableBehaviour;

    public Transform myModelPrefab;

    // Use this for initialization
    void Start ()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();

        if (mTrackableBehaviour)
        {
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
    }               

    // Update is called once per frame
    void Update ()
    {
    }

    public void OnTrackableStateChanged(
              TrackableBehaviour.Status previousStatus,
              TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED)
        {
            OnTrackingFound();
        }
    }
    private void OnTrackingFound()
    {
        if (myModelPrefab != null)
        {
            Transform myModelTrf = GameObject.Instantiate(myModelPrefab) as Transform;

             myModelTrf.parent = mTrackableBehaviour.transform;             
             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;
         }
     }
}

 

 

  • As you can see from the code, the MyModelInstantiator class implements the ITrackableEventHandler interface, so that it is notified of when the target is detected; at that point, the Prefab 3D model gets instantiated and attached under the image target; the position and scale are adjusted so that the model can augment the target nicely (please adjust the values of the position, rotation and scale to fit your needs for the specific model)
  • Also, the script contains a public Transform variable called MyPrefabModel; if you now go back to the Unity scene view and you click on the “chips” image target, in the inspector you will see that the MyModelInstantiator script now exposes a field called “My Prefab Model”; select your prefab in the Prefabs folder (in the project view) and drag it onto the “My Prefab Model” field in the MyModelInstantiator script component.

Save the project, build and run the app: as soon as the chips target is detected, your prefab 3D model should appear on top of it.

If the size of the model is either too small or too big, go to the script code and adjust the localScale values.

 

 

 

 

 

 

 

Topic locked