Search code examples
c++unity-game-engineaugmented-realityvuforiaimage-recognition

Vuforia -- how to only play one video when an image is recognized


I have an AR application that has 4 image targets, and each image target has a corresponding video that is played on top of it when it is recognized. The problem is that even though the correct animation is displayed whenever the image is recognized, all of the other animations are played as well, even though they are not displayed. Thus, whenever I move from one image target to another, the video is displayed, but it is already halfway through its runtime.

I want each video to start whenever its parent image target is recognized, but only that specific video. I need control of the trackable behavior for each image target/video.

how can i do that? I know that the scripts I need to look at in Unity are DefaultTrackableEventHandler.cs or mediaPlayerCtrl.cs (which is a scrip that I am using for my video manager(video player) that I got from the Easy Movie Texture asset. What is the code that I need to write in those scripts to make it happen. Here is the DefaultTrackableEventHandler.cs code:

using UnityEngine;
using Vuforia;

/// <summary>
///     A custom handler that implements the ITrackableEventHandler 
interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour, 
ITrackableEventHandler
{
#region PRIVATE_MEMBER_VARIABLES

protected TrackableBehaviour mTrackableBehaviour;

#endregion // PRIVATE_MEMBER_VARIABLES

#region UNTIY_MONOBEHAVIOUR_METHODS

protected virtual 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)
    {
        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
        OnTrackingFound();
    }
    else if (previousStatus == TrackableBehaviour.Status.TRACKED &&
             newStatus == TrackableBehaviour.Status.NOT_FOUND)
    {
        Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
        OnTrackingLost();
    }
    else
    {
        // For combo of previousStatus=UNKNOWN + newStatus=UNKNOWN|NOT_FOUND
        // Vuforia is starting, but tracking has not been lost or found yet
        // Call OnTrackingLost() to hide the augmentations
        OnTrackingLost();
    }
}

#endregion // PUBLIC_METHODS

#region PRIVATE_METHODS

protected virtual void OnTrackingFound()
{
    var rendererComponents = GetComponentsInChildren<Renderer>(true);
    var colliderComponents = GetComponentsInChildren<Collider>(true);
    var canvasComponents = GetComponentsInChildren<Canvas>(true);

    // Enable rendering:
    foreach (var component in rendererComponents)
        component.enabled = true;

    // Enable colliders:
    foreach (var component in colliderComponents)
        component.enabled = true;

    // Enable canvas':
    foreach (var component in canvasComponents)
        component.enabled = true;
}


protected virtual void OnTrackingLost()
{
    var rendererComponents = GetComponentsInChildren<Renderer>(true);
    var colliderComponents = GetComponentsInChildren<Collider>(true);
    var canvasComponents = GetComponentsInChildren<Canvas>(true);

    // Disable rendering:
    foreach (var component in rendererComponents)
        component.enabled = false;

    // Disable colliders:
    foreach (var component in colliderComponents)
        component.enabled = false;

    // Disable canvas':
    foreach (var component in canvasComponents)
        component.enabled = false;
}

#endregion // PRIVATE_METHODS
}

Solution

  • You have to stop the video everytime tracking is lost, and start it again when tracking is found. I don't know exactly how your video asset work, but I will use generic names/functions so you get the idea

    protected virtual void OnTrackingLost()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);
        var myVideo = GetComponentInChildren<TheVideoClassAttachedToChildOfImageTarget>
    
        // Disable rendering:
        foreach (var component in rendererComponents)
            component.enabled = false;
    
        // Disable colliders:
        foreach (var component in colliderComponents)
            component.enabled = false;
    
        // Disable canvas':
        foreach (var component in canvasComponents)
            component.enabled = false;
    
        // Stop video
        myVideo.Stop();
    }
    

    Similarly for OnTrackingFound

    protected virtual void OnTrackingFound()
    {
        var rendererComponents = GetComponentsInChildren<Renderer>(true);
        var colliderComponents = GetComponentsInChildren<Collider>(true);
        var canvasComponents = GetComponentsInChildren<Canvas>(true);
        var myVideo = GetComponentInChildren<TheVideoClassAttachedToChildOfImageTarget>
    
        // Enable rendering:
        foreach (var component in rendererComponents)
            component.enabled = true;
    
        // Enable colliders:
        foreach (var component in colliderComponents)
            component.enabled = true;
    
        // Enable canvas':
        foreach (var component in canvasComponents)
            component.enabled = true;
    
        // Play the video again from the beggining
        myVideo.Play();
    }