Solid_Metal
Solid_Metal

Reputation: 133

Check if ARCamera first time detect the marker and "spawn" the 3d object

i'm trying to make a simple AR app, the flow of the app i try to make is, camera detect first marker > do something, camera detect 2nd marker > do something different

the problem is i already googled with combination of keyword i can think of, and also i also look for the documentation but nothing really i can found that help with my problem

my initial though is to just use a script on the said marker and put the "do something" on void OnEnable, but the object is enable anyway, so its useless

anyone can lend me a rope ?

Upvotes: 1

Views: 1575

Answers (2)

Dimitar
Dimitar

Reputation: 4793

Starting in 8.6.7, Vuforia have refactored ITrackableEventHandler into a base class DefaultTrackableEventHandler instead of an interface.

public class MyTrackableEventHandler : DefaultTrackableEventHandler
{
    ...
}

Further, the callbacks RegisterTrackableEventHandler and UnregisterTrackableEventHandler also need to be updated. This now uses a callback method.

private void OnEnable()
{
    _trackableBehaviour = GetComponent<TrackableBehaviour>();
    _trackableBehaviour.RegisterOnTrackableStatusChanged(OnTrackableStateChanged);
}

private void OnDisable()
{
    _trackableBehaviour.RegisterOnTrackableStatusChanged(OnTrackableStateChanged);
}

public void OnTrackableStateChanged(StatusChangeResult obj)
{

    if (obj.NewStatus == Status.DETECTED || obj.NewStatus == Status.TRACKED
        || obj.NewStatus == Status.EXTENDED_TRACKED)
    {
        OnTrackingFound();
    }
    else
        OnTrackingLost();
}

Upvotes: 0

Everts
Everts

Reputation: 10701

DefaultTrackingEventHandler is the script handling the tracking. In the sample scene for multiple markes, it is attached to ImageTarget.

That script registers to the TrackableBehaviour and propagates the tracking found/lost via the OnTrackingFound/Lost methods.

In the sample scene, those methods collect the collider and renderer of the child object and enables/disables.

What you can do is to propagate further the info to other listeners. In this case you could enable a script that runs an update checking for a condition until it is met and disable the script and matching trackable behaviour.

public class DefaultTrackableEventHandler : MonoBehaviour,
                                            ITrackableEventHandler
{
    private TrackableBehaviour mTrackableBehaviour;
    [SerializedField] private MyConditionClass actionMb = null;
    protected virtual void Start()
    {
        mTrackableBehaviour = GetComponent<TrackableBehaviour>();
        if (mTrackableBehaviour)
        {
            mTrackableBehaviour.RegisterTrackableEventHandler(this);
        }
    }

    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();
        }
    }

    protected virtual void OnTrackingFound()
    {
        // Was already successfully done
        if(this.actionMb.ConditionMet == true){ return; }
        this.actionMb.enable = true;
    }


    protected virtual void OnTrackingLost()
    {
        // Was already successfully done
        if(this.actionMb.ConditionMet == true){ return; }
        this.actionMb.enable = false;
    }
}

public abstract class MyConditionClass : MonoBehaviour
{   
    public bool ConditionMet{ get; private set; }
    protected abstract bool CheckCondition();
    protected virtual void Update(){
        if(ConditionMet == true){ return; }
        ConditionMet = CheckCondition();
    }
}  

public class MyConditionClassForInput : MyConditionClass 
{   
    protected override bool CheckCondition(){
        return (Input.GetKeyDown(KeyCode.Space));
    }
}

So you have a base class containing the data that should be common to all conditions, like whether the condition was already met as shown. and the Update running a condition check.

Then you have sub class that implements the condition check (has to since abstract).

Upvotes: 2

Related Questions