I want to place a UI button based on the image target. I am using Vuforia engine and I have an image which has chairs and tables. So I want to place a button on the UI (not a virtual button) based on image. For example, one button should be on the chair. When I move, the button should re-adjust to always show up over the chair and when clicked, it should display a 3d text saying that its a chair. I am a new to AR and wanted to explore onto some of such tutorials.
You can place UI elements in 3D space by choosing WorldSpace
for the RenderMode
a Canvas
(also see the Manual) via the inspector.
Than you can simply make that Canvas
GameObject
a child of the according ImageTarget. So that whenever the ImageTarget is moved (by the tracking) the Canvas
is automatically moved along without having to take care of it.
Alternative you could also move and place the object with that Canvas
attached like any other object in a component e.g.
public class PlaceCanvasOnTarget : MonoBehaviour
{
public Transform ImageTarget;
public Canvas CanvasToPlace;
// set an offset for the canvas e.g. 20cm above
public Vector3 offset = new Vector3(0, 0.2, 0);
private void LateUpdate()
{
Canvas.transform.position = ImageTarget.transform.position + offset;
}
}
Additionally afaik the childs of an ImageTarget by default get not all disabled onTrackingLost and enabled onTrackingFound. Only some components are disabled but you can change this by copying the content of DefaultTrackableEventHandler
to a custom one and adjust it something like (important for you are only OnTrackingFound
and OnTrackingLost
at the bottom)
using UnityEngine;
namespace Vuforia
{
/// <summary>
/// A custom handler that implements the ITrackableEventHandler interface.
/// </summary>
public class DefaultTrackableEventHandler : MonoBehaviour,
ITrackableEventHandler
{
#region PRIVATE_MEMBER_VARIABLES
private TrackableBehaviour mTrackableBehaviour;
#endregion // PRIVATE_MEMBER_VARIABLES
#region UNTIY_MONOBEHAVIOUR_METHODS
void Start()
{
mTrackableBehaviour = GetComponent<TrackableBehaviour>();
if (mTrackableBehaviour)
{
mTrackableBehaviour.RegisterTrackableEventHandler(this);
}
}
#endregion // UNTIY_MONOBEHAVIOUR_METHODS
#region PUBLIC_METHODS
public GameObject show;
public GameObject hide;
/// <summary>
/// Implementation of the ITrackableEventHandler function called when the
/// tracking state changes.
/// </summary>
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();
}
}
#endregion // PUBLIC_METHODS
#region PRIVATE_METHODS
private void OnTrackingFound()
{
show.SetActive(true);
// enabled all children
foreach(Transform child in transform)
{
child.gameObject.SetActive(true);
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " found");
}
private void OnTrackingLost()
{
hide.SetActive(true);
// disable all children
foreach(Transform child in transform)
{
child.gameObject.SetActive(false);
}
Debug.Log("Trackable " + mTrackableBehaviour.TrackableName + " lost");
}
#endregion // PRIVATE_METHODS
}
}
For the button showing and hiding some text:
Add a Button
as child to the Canvas
.
Add a Panel
as child to the Canvas
. And add a Text
as child to that Panel
. (You don't need to use a Panel - it is basically just an Image
component - but it might be easier to read the Text if it placed on a semitransparent or opaque surface instead of just "floating" in the air)
Than make a simple component
public TogglePanel : MonoBehaviour
{
public void Toggle()
{
gameObject.SetActive(!gameObject.activeSelf);
}
}
Attach that component to the Panel
object
In the Button
's onClick
event now reference the TogglePanel
component and select the method TogglePanel
->Toggle()
The result should be now
OnTracking lost: Canvas (Button and Panel with Text) disapears
OnTracking found: Canvas (Button and evtl Panel with Text) appears and should always be on top of the chair (imageTarget);
OnButtonClick: Panel with Text should get enabled or disabled