Pause animation with Vuforia

Hi everybody,

I’m doing a little Vuforia project with Unity and am desperately searching for a way to pause my animation when the tracker is lost and have it continue at the same position as soon as the imagetracker is back on screen. Pretty much the same way it works with audio ( component.audio.Pause(); ). I have read on the Unity forums here that the way to pause an animation is to set the speed of the animation to 0 but how do i add that to my code? Right now the OnTrackingFound says:

Animation[ ] animationComponents = GetComponentsInChildren();

foreach (Animation component in animationComponents)

{ component.Play(); }

which triggers the animation. But where to put the speed variable? :confused:
I know somebody can help me around here! :slight_smile:
Thank you in advance!

Hi Dariok,

You can do it like this:
animation[“Walk”].speed = 0.0F;

see doc:

Best regards,

ok thank you!
but where exactly should i put this in the script? since i don’t call a specific animation like the [“Walk”] one.
This is pretty much all the code for the animation event:

// *** Additional animation code
Animation[ ] animationComponents = GetComponentsInChildren();

foreach (Animation component in animationComponents)
{
component.Play();
}

// *** end of animation code

…I guess I don’t have to tell you that I don’t know much about scripting :S

You can iterate throught all Animationstate like this:

public class ExampleClass : MonoBehaviour {
    void Example() {
        foreach (AnimationState state in animation) {
            state.speed = 0.0F;
        }
    }
}

Thanks a lot for your help! But I’m still not getting it to work… here is the complete script that I’m using:

public class DefaultTrackableEventHandler : MonoBehaviour,
                                            ITrackableEventHandler
{
    #region PRIVATE_MEMBER_VARIABLES
    private TrackableBehaviour mTrackableBehaviour;
   
    #endregion // PRIVATE_MEMBER_VARIABLES



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

    #endregion // UNTIY_MONOBEHAVIOUR_METHODS



    #region PUBLIC_METHODS

    /// <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()
    {
        Renderer[] rendererComponents = GetComponentsInChildren<Renderer>(true);
        Collider[] colliderComponents = GetComponentsInChildren<Collider>(true);

        // *** Additional animation code
        Animation[] animationComponents = GetComponentsInChildren<Animation>();
       
        foreach (Animation component in animationComponents)
        {
            component.Play();
        }

        // *** end of animation code
   

        // Enable rendering:
        foreach (Renderer component in rendererComponents)
        {
            component.enabled = true;
        }
        // *** Code for Audiostart
        AudioSource[] audioComponents = GetComponentsInChildren<AudioSource>();
        foreach (AudioSource component in audioComponents)
        {
            component.audio.Play();   
        }
        // *** end of audio code

        // 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;
        }

        // *** Code for Audiostop
        AudioSource[] audioComponents = GetComponentsInChildren<AudioSource>();
        foreach (AudioSource component in audioComponents)
        {
            component.audio.Pause();
        }
        // *** end of audio code

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

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

    #endregion // PRIVATE_METHODS
}

I assume that the additional AnimationState code has to go somewhere in the “private void OnTrackingFound” and “OnTrackingLost” but i can’t figure out the needed equivalent to the “Animation[ ] animationComponents = GetComponentsInChildren();” -part

The closest I got to the wanted result is this error message:
MissingComponentException: There is no ‘Animation’ attached to the “ImageTarget3” game object, but a script is trying to access it.
“You probably need to add a Animation to the game object “ImageTarget3”. Or your script needs to check if the component is attached before using it.”

Again thank you for your help, I really appreciate this!

Hum are you sure your game object have an Animation component, look like no.

Maybe you are using an Animator component? If it the case then you can simply do

Animator animator = GetComponent<Animator>();
animator.speed = 0.0f;

Sadly, that’s not it either :frowning:
I don’t know if you have worked with the vuforia plugin before? There’s a hierarchy with a so called ImageTarget which is the tracker image onto which the models are transferred and in it are the GameObjects that have the animations. The problem seems to be that the new animation state part tries to find an animation in the ImageTarget, when there’s only animations in it’s children objects. So I guess that I’m missing a line similar to this:

Animation[] animationComponents = GetComponentsInChildren<Animation>();

to tell the script that it has to look for animations in the children or some kind of “if-question” to see if there are any animations. But I can’t figure it out :confused:

EDIT:
Ok I got it!! This is the code to use if anybody is interested:

    // *** Start of animation code
        Animation[] animationComponents = GetComponentsInChildren<Animation>();

        foreach (Animation animation in animationComponents)
        {
            foreach (AnimationState animState in animation)
            {
                animState.speed = 1f;
                animation.Play();
            }
        }

        // *** end of animation code

This is what you put in the OnTrackingFound and in the OnTrackingLost just change the animState.speed to 0 and leave out the “animation.Play();”

Thanks a lot for your help Mecanim.Dev! :slight_smile:

1 Like