Search code examples
c#unity-game-enginevuforia

Objects with gravity fall continuously before Image Target renders


I'm trying to render some content onto an Image Target and one of the objects has a Rigidbody with gravity. The object with gravity starts to fall as soon as the scene starts, but the image target has not been recognized yet so it keeps falling forever.

I saw some code online suggesting to implement ITrackableEventHandler but the guide on Vuforia's site doesn't work anymore.

The code Vuforia suggests is below:

using UnityEngine;
using Vuforia;
using System.Collections;
public class MyPrefabInstantiator : MonoBehaviour, ITrackableEventHandler {
  private TrackableBehaviour mTrackableBehaviour;
  public Transform myModelPrefab;
  // Use this for initialization
  void Start ()
  {
    mTrackableBehaviour = GetComponent<TrackableBehaviour>();
    if (mTrackableBehaviour) {
      mTrackableBehaviour.RegisterTrackableEventHandler(this);
    }
  }
  // Update is called once per frame
  void Update ()
  {
  }
  public void OnTrackableStateChanged(
    TrackableBehaviour.Status previousStatus,
    TrackableBehaviour.Status newStatus)
  { 
    if (newStatus == TrackableBehaviour.Status.DETECTED ||
        newStatus == TrackableBehaviour.Status.TRACKED ||
        newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)
    {
      OnTrackingFound();
    }
  } 
  private void OnTrackingFound()
  {
    if (myModelPrefab != null)
    {
      Transform myModelTrf = GameObject.Instantiate(myModelPrefab) as Transform;
      myModelTrf.parent = mTrackableBehaviour.transform;
      myModelTrf.localPosition = new Vector3(0f, 0f, 0f);
      myModelTrf.localRotation = Quaternion.identity;
      myModelTrf.localScale = new Vector3(0.0005f, 0.0005f, 0.0005f);
      myModelTrf.gameObject.active = true;
    }
  }
}

Solution

  • Vuforia has implemented ITrackableEventHandler for you with the class DefaultTrackableEventHandler

    You can enable and disable gravity with a script like this:

    using UnityEngine;
    
    public class EnablePlayerGravity : DefaultTrackableEventHandler
    {
        public Rigidbody player;
    
        override protected void OnTrackingLost()
        {
            player.useGravity = false;
        }
        override protected void OnTrackingFound()
        {
            player.useGravity = true;
        }
    }
    

    You don't need to register this with the ImageTarget's TrackableBehavior because the Start method of DefaultTrackableEventHandler already does that for you. All you need to do is drop this script onto your ImageTarget and then set the player's (or whichever object has gravity) Rigidbody in the inspector.