I noticed that a video placed on a quad that is a child of a Vuforia image target starts playing immediately. I found a very detailed tutorial that addresses this specific issue by editing the DefaultTrackableEventHandler script. Unfortunately, the changes to the script generate errors in my development setting. The tutorial was done with Unity3D 2017.3 and Vuforia 7. I am using 2018.3.0f2 personal version and Vuforia 7.5.26. This issue was addressed at time 32:05 in the following video: https://youtu.be/4W5e6-TSpW0
I have done my due diligence looking at the core samples including the fissure image target in the 3-ImageTargets scene. I have Googled the topic to death, and canāt get it working. I am including the script from the YouTube tutorial in case someone with experience can spot what needs to be changed. I would be incredibly grateful for the help!
/*==============================================================================
Copyright (c) 2017 PTC Inc. All Rights Reserved.
Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Protected under copyright and other laws.
==============================================================================*/
using UnityEngine;
using Vuforia;
// need to import video functionality
using UnityEngine.Video;
[RequireComponent(typeof(VideoPlayer))]
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour, ITrackableEventHandler
{
#region PRIVATE_MEMBER_VARIABLES
protected TrackableBehaviour mTrackableBehaviour;
// setup the videoPlayer object
private VideoPlayer videoPlayer;
#endregion // PRIVATE_MEMBER_VARIABLES
#region UNTIY_MONOBEHAVIOUR_METHODS
protected virtual void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
mTrackableBehaviour.RegisterTrackableEventHandler(this);
// add the following 4 lines to get the reference to the video player component of the plane that the video is attached to
// IMPORTANT: set "Video_plane" to the name of the plane game object you attached your video to
GameObject video = GameObject.Find ("Video_plane");
videoPlayer = video.GetComponent<VideoPlayer>();
videoPlayer.Play();
videoPlayer.Pause();
// see the VideoPlayer Scripting API for more ideas on which functions you can use in your code
// for example changing the playback speed or jumping to a speicific point in time:
// https://docs.unity3d.com/ScriptReference/Video.VideoPlayer.html
}
#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");
// Play the video:
Debug.Log("Play!");
OnTrackingFound();
videoPlayer.Play();
}
else if (previousStatus == TrackableBehaviour.Status.TRACKED &&
newStatus == TrackableBehaviour.Status.NOT_FOUND)
{
//Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
// Pause the video, if using Stop() the video would always play back from the beginning again
Debug.Log("Stop!");
OnTrackingLost();
videoPlayer.Pause();
}
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
As far as the script is concerned, the only error it gave me was āAssets/VideoPlay.cs(72,49): error CS0117: āTrackableBehaviour.Statusā does not contain a definition for āNOT_FOUNDāā. Iāve fixed the error, but unfortunately the script is not solving the original problem. When the app is started, the videoās (before they are detected) start playing. The audio, however, only starts playing when a target is detected. Therefore, the audio and video donāt align.
(Iāve created a short video in which I demonstrate the issue, you can find it here: Arvideotest.mp4 - Google Drive . sorry for the crappy quality, my computer wonāt record the screen.)
My question would be: Is there a function to stop (not pause) the video when target is lost? Iām using this piece of code for the audio:
void StopAllAudio()
{
allAudioSources = FindObjectsOfType(typeof(AudioSource)) as AudioSource[];
foreach (AudioSource audioS in allAudioSources)
{
audioS.Stop();
}
}
Why would you want to stop / start the audiosource separately? The videoplayer should do so automatically, assuming youāre playing the audio embedded in the video file and not a separate audio file.
Could you post your entire trackable eventhandler script? I downloaded the adapted script from the youtube tutorial and it doesnāt mention audiosources.
Iām playing the audio as a separate audio file, because when I had the audio embedded in the video file, it did not mute/pause/stop the audio when the target was lost. This resulted in the audio looping indefinitely without a target being present (I made a video in which I demonstrate this issue: AR_test_Diggit Magazine.mp4 - Google Drive)
Hereās my current code:
/*==============================================================================
Copyright (c) 2010-2014 Qualcomm Connected Experiences, Inc.
All Rights Reserved.
Confidential and Proprietary - Protected under copyright and other laws.
==============================================================================*/
using UnityEngine;
//Add This script
using System.Collections;
using System.Collections.Generic;
namespace Vuforia
{
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour,
ITrackableEventHandler
{
//------------Begin Sound----------
public AudioSource soundTarget;
public AudioClip clipTarget;
private AudioSource[] allAudioSources;
//function to stop all sounds
void StopAllAudio()
{
allAudioSources = FindObjectsOfType(typeof(AudioSource)) as AudioSource[];
foreach (AudioSource audioS in allAudioSources)
{
audioS.Stop();
}
}
//function to play sound
void playSound(string ss)
{
clipTarget = (AudioClip)Resources.Load(ss);
soundTarget.clip = clipTarget;
soundTarget.loop = false;
soundTarget.playOnAwake = false;
soundTarget.Play();
}
//-----------End Sound------------
#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);
}
//Register / add the AudioSource as object
soundTarget = (AudioSource)gameObject.AddComponent<AudioSource>();
}
#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);
// Enable rendering:
foreach (Renderer component in rendererComponents)
{
component.enabled = true;
}
// Enable colliders:
foreach (Collider component in colliderComponents)
{
component.enabled = true;
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
//Play Sound, IF detect an target
if (mTrackableBehaviour.TrackableName == "AR_Jan-1")
{
playSound("audio/AR_Jan 1_audio");
}
if (mTrackableBehaviour.TrackableName == "AR_Odile-1")
{
playSound("audio/AR_Odile 1_audio");
}
}
private void OnTrackingLost()
{
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");
//Stop All Sounds if Target Lost
StopAllAudio();
}
#endregion // PRIVATE_METHODS
}
}
Iām happy with the way itās handling the audio at this moment. If the video-part could do the exact same thing as the audio-part, Iād be very happy. Hope youāre able to help.
Can you tell me how you solved this? āAssets/VideoPlay.cs(72,49): error CS0117: āTrackableBehaviour.Statusā does not contain a definition for āNOT_FOUNDāā
I am having similar issues.
An Ar camera
ImageTarget with QUAD as child with the video player component.
I have tried with embedded audio, a separate audio source
Play on Awake On and off.
But its never correct.
The audio either starts immediately before the tracked image is found, and just carries on. The video does not pause when it stops tracking.
Any help would b appreciated.
jm
So Iām using Unity 2020.3 I had the same issue, I was able to fix it by going to the āimage targetā ā āVideo Trackable Event Handlerā and changing the āStatus Filterā from āTracked_Extended Trackedā to āTrackedā
Also thank you for the link to the Lecture, I needed to use the scripts he provided to get it to work