Search code examples
c#unity-game-enginevuforia

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 ?


Solution

  • 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).