Dungeon
Dungeon

Reputation: 1040

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!

Upvotes: 0

Views: 1464

Answers (2)

derHugo
derHugo

Reputation: 90570

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.

Upvotes: 2

Muhammad Farhan Aqeel
Muhammad Farhan Aqeel

Reputation: 717

I am using a modified version of DefaultTrackableEventHandler.cs for this. as i didn't want to change vuforia's own code so i copied all the content and created a new script. here is the code that may solve your issue.

You can set a bool to mark whether you have tracked a marker or not. if it has not tracked the marker it will disable the 3d model(Quad), otherwise, it will work as normal. You can add another condition to check whether the newly tracked marker is different than the other one.

Code:

    if (_isTracked)
    return;

    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;

Upvotes: 0

Related Questions