Search code examples
unity-game-engineaugmented-realityvuforia

Attach the target model to screen even when target image is lost in Vuforia?


I am using Unity 5 and vuforia 8.1. I have some odd requirement that when the target image is found modal should be displayed on the screen but when camera is out of target it should still be there.

I am playing green screen video over my target image. What should I do to implement my requirement. By now I'm attaching a Quad to Image Target and then attaching video player. enter image description here

What I tried:

I visited this link. But couldn't achieved my result. Any help would be much appreciated. Thanks!


Solution

  • I personally don't like how Vuforia sets up the objects. It only makes sense if an image target is permanently tracked.

    I usually completely separate the tracking from the objects I want to position.

    For this I use a customized DefaultTrackableEventHandler extending it with UnityEvents (similar to onClick of the UI.Button)

    // We need a custom UnityEvent for passing on the 
    // ImageTargets transform reference
    [Serializable]
    public class TransformEvent : UnityEvent<Transform> { }
    
    public class VuforiaTargetEvents : DefaultTrackableEventHandler
    {
        public TransformEvent onTargetFound;
        public TransformEvent whileTargetTracked;
        public TransformEvent onTargetLost;
    
        protected override void OnTrackingFound()
        {
            base.OnTrackingFound();
    
            onTargetFound.Invoke(transform);
    
            StopAllCoroutines();
            StartCoroutine(WhileTracked());
        }
    
        protected override void OnTrackingLost()
        {
            base.OnTrackingLost();
    
            onTargetLost.Invoke(transform);
    
            StopAllCoroutines();
        } 
    
        // For more information about Coroutines see
        // https://docs.unity3d.com/Manual/Coroutines.html
        private IEnumerator WhileTracked()
        {
            // looks dangerous but is ok inside a Coroutine 
            // as long as you yield somewhere
            while(true)
            {
                whileTargetTracked.Invoke(transform);
                yield return null;
            }
        }
    }
    

    Place this component on the ImageTarget.

    Place the Quad separately somewhere in the Scene and attach the following component to it

    public class PlaceOnImageTarget : MonoBehaviour
    {
        // In the Inspector configure
        // if this object should be enabled or disabled at start
        public bool startEnabled;
    
        private void Awake()
        {
            gameObject.SetActive(startEnabled);
        }
    
        public void UpdatePosition(Transform imageTarget)
        {
            transform.position = imageTarget.position;
            transform.rotation = imageTarget.rotation;
    
            gameObject.SetActive(true);
        }
    }
    

    now in the ImageTarget in the onTargetFound event add 1 element and drag in the Quad object. Than select from the list the method PlaceOnImageTarget -> UpdatePosition (make sure to select the one that says dynamic -> it should give no field for input but instead will use the value we pass in when invoking the event)

    If you want that it is permanently updated while the ImageTarget is tracked repeat the same also for the whileTargetTracked event.


    Typed on smartphone so no warranty but I hope the idea gets clear.