VUFORIA: Playing an animation for a instanced model?

Hey everyone,

I’m 100% NOT a coder, so please help me!
I’m using Vuforia for VR and AR stuff, and I’m trying to instance my model onto an image target from my Prefabs folder (I’m instancing from the folder because I couldn’t get it to show up any way else, if anyone knows a better way, PLEASE let me know!)

In this code, I’m trying to instance the model onto the image target and play its animation, which is just a walking animation. But, I can’t get it to work! I haven’t ever used C# before, and I’ve barely even coded at all. I don’t even know how to approach this!

I’ve tried the basic animation.Play() command, but with no luck… I literally don’t know what else to do besides that.
Here’s my code.

using UnityEngine;
using System.Collections;
using Vuforia;
 
public class MyOtherPrefabInstantiator : MonoBehaviour, ITrackableEventHandler 
{
    private TrackableBehaviour mTrackableBehaviour;
 
    public Transform myModelPrefab;
 
    // Use this for initialization
    void Start ()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
 
        if (mTrackableBehaviour)
        {
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
    }
 
    public void OnTrackableStateChanged(
              TrackableBehaviour.Status previousStatus,
              TrackableBehaviour.Status newStatus)
    {
        if (newStatus == TrackableBehaviour.Status.DETECTED ||
            newStatus == TrackableBehaviour.Status.TRACKED ||
            newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
        {
            OnTrackingFound();
        }
    }
    private void OnTrackingFound()
    {
        if (myModelPrefab != null)
        {

            Transform myModelTrf = GameObject.Instantiate(myModelPrefab) as Transform;
 
             myModelTrf.parent = mTrackableBehaviour.transform;             
             myModelTrf.localPosition = new Vector3(-0.3f, 0f, 0.3f);
             myModelTrf.localRotation = Quaternion.identity;
             myModelTrf.localScale = new Vector3(0.35f, 0.35f, 0.35f);

			 myModelTrf.GetComponent<Animation>().Play("");
 
             myModelTrf.gameObject.active = true;
         }
     }
}

I’ve tried messing around with it in a few different places, but with no luck. I’m just blindly doing stuff here.

Please be kind. haha I seriously don’t know what I’m doing here. Any and all help is greatly appreciated!!!

What exactly is not working? If you don’t know what you are doing :slight_smile: I would start like this:

  • Drag the ARCamera Prefab to the scene
  • Add an ImageTarget Prefab to the scene
  • Make a new script with the same content as the DefaultTrackableEventHandler and exchange it with the one on the ImageTarget (use this script for editing to avoid to mess up the original :slight_smile: )
  • Setup the correct data base in the
    inspector (ARCamera and ImageTarget)
  • Drag your model prefab onto the image
    target (so it becomes a child of it)
  • And THEN start playing around with
    the animation in OnTrackingFound()
    right after the Renderer components
    are enabled (after the foreach loop)

Atm you are instantiating a new Transform every time the marker (tracking image) is found and unless you don’t destroy it again in OnTrackingLost() you’ll end up with a lot of clones of your model in the scene. If you want to instantiate it, just do it at Start(). OnTrackingFound() and OnTrackingLost() will enable/disable the Renderer component if the transform is set as a child of the ImageTarget. You ‘only’ have to tell unity to restart the animation in OnTrackingFound().

I just can’t get the animation to play. The model appears, but it doesn’t move or play the animation.

So for the steps you’ve given me, I’ve tried those a ton. I haven’t been able to get the model to even appear over the image target when it is a child under the image target. All I did to the code though was change the names to fit the models. Also, is it important that I have DefaultTrackableEventHandler? i don’t have it anywhere on my computer, but I have ImageTargetTrackableEventHandler. Is that the same thing? here’s what it looks like.

* Copyright (c) 2012-2014 Qualcomm Connected Experiences, Inc. All Rights Reserved. 
 * ==============================================================================*/

using UnityEngine;
using Vuforia;

/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class ImageTargetTrackableEventHandler2 : MonoBehaviour,
                                            ITrackableEventHandler
{
    #region PUBLIC_MEMBER_VARIABLES
    public bool isBeingTracked;
    #endregion PUBLIC_MEMBER_VARIABLES
    
    #region PRIVATE_MEMBER_VARIABLES
    private TrackableBehaviour mTrackableBehaviour;
    #endregion // PRIVATE_MEMBER_VARIABLES

    #region PUBLIC_METODS
    void Start()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
        if (mTrackableBehaviour)
        {
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
    }
    

    /// <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)
        {
            OnTrackingFound();
        }
        else
        {
            OnTrackingLost();
        }
    }

    #endregion // PUBLIC_METHODS



    #region PRIVATE_METHODS
    private void OnTrackingFound()
    {
        isBeingTracked = true;
        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

        // Enable rendering:
        foreach (Renderer component in rendererComponents)
        {
            if(ImageTargetUIEventHandler.ExtendedTrackingIsEnabled)
            {
                if(component.gameObject.name == "RobotModel")
                {
                     component.enabled = true;
                }
				if(component.gameObject.name == "AnimatedRobot")
				{
					component.enabled = true;
					GameObject go = GameObject.Find("AnimatedRobot");
									go.GetComponent<Animation>().Play("robotcontrol");
				}
            }
            else if(component.gameObject.name == "")
            {
                component.enabled = true;
				GameObject go = GameObject.Find("");
								go.GetComponent<Animation>().Play("");
            }
        }

        // Enable colliders:
        foreach (Collider component in colliderComponents)
        {
             if(ImageTargetUIEventHandler.ExtendedTrackingIsEnabled)
                {
                    if(component.gameObject.name == "RobotModel")
                    {
                         component.enabled = true;
                    }
				}
			if(component.gameObject.name == "AnimatedRobot")
				{
					component.enabled = true;
					//GameObject go = GameObject.Find("Catwalk2");
									//go.GetComponent<Animation>().Play("Catwalk2");
				}
                
            else if(component.gameObject.name == "")
            {
                component.enabled = true;
            }
        }

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


    private void OnTrackingLost()
    {
        isBeingTracked = false;
        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");
    }

    #endregion // PRIVATE_METHODS
}

I’ve seen in a few places that I need a .h file of the model’s information or something? Or is that for OpenGLES only? Is there an easier way to do this with Unity? I’m so confused with all this.

Let me explain my whole scene. I have two image targets, and I want one non-animated model of a robot to appear on one, and I want one animated model of a robot to appear on the other one. Do I need two separate pieces of code for both, or can I use the same script for both? Should I be able to simply parent the model under the image target and change the name in the code? Or do I have to do something else…?

I’m sorry, I’m just all over the place. I’ve read so much about this that everything is blending together and I don’t even know what I’m saying.

And thanks for the advice on the instantiator code, I was wondering why it was just creating more and more clones.
Sorry that this is so all over the place. :frowning: i’m so confused about this whole thing.