unity3d - Show on-screen UI Button in Unity Augmented Reality


Keywords:unity3d 


Question: 

I am new to Unity and Vuforia. I am trying to create an augmented reality experience where the user can scan across a target marker and it will reveal a button that they can click on.

I was able to set up an ARCamera and ImageTarget with a child GameObject cube. When I scan my marker with my iPad, I can see the cube hovering over my marker. Great.

Now, I am trying to get the cube to become a clickable button so I tried using a UI Button. However, creating any UI object means that it comes with a UI Canvas as well. So, I want to be able to scan the marker and have the button show up but that is not working. The button is simply just there on the screen regardless of whether or not I scan over the marker.

What should my hierarchy look like?

ARCamera

-> Camera

ImageTarget

-> Canvas

->-> Button

->->-> Text

Or should it be:

ARCamera

-> Camera

Canvas

-> ImageTarget

->-> Button

->->->Text

What do I do with two ImageTargets? Should I use the first hierarchy or second?

Finally, what should my canvas Render Mode be? I currently have it as "Screen Space - Overlay." I tried "Screen Space - Camera" but it didn't really make that much of a difference. The buttons still did not show up when scanning the marker.


1 Answer: 

You need to show button when traceable "ImageTarget" found. i.e. button should be popup on traceable event.

  • If you create such simple UI in unity , wherever you place it in hierarchy . it will always display regardless of marker detection.
  • You first need to know marker get detected or not using method provided by Vuforia and then have to create button grammatically.
  • For this you must understand how to keep a track of trackable events, such as trackable found or trackable lost. Vuforia makes this easy for us by providing a template script named DefaultTrackableEventHandler.

  • This script is by default attached to any ImageTarget prefab. You can use this script or similar script as shown below.

    if (newStatus == TrackableBehaviour.Status.DETECTED || newStatus == TrackableBehaviour.Status.TRACKED || newStatus == TrackableBehaviour.Status.EXTENDED_TRACKED)

You have to write C# script and attach it to "ImageTarget"

Script below describes how to show (popup) a GUI button overlaid on top of the 3D view in response to a target detection event, using thre Unity extension of the Vuforia SDK.

Here is the Script

using UnityEngine;
using System.Collections;
using Vuforia;
using System;

public class ButtonPopup : MonoBehaviour, ITrackableEventHandler {

    float native_width= 1920f;
    float native_height= 1080f;
    public Texture btntexture;
    public Texture LogoTexture;
    public Texture MobiliyaTexture;


    private TrackableBehaviour mTrackableBehaviour;

    private bool mShowGUIButton = false;


    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)
        {
            mShowGUIButton = true;
        }
        else
        {
            mShowGUIButton = false;
        }
    }

    void OnGUI() {

        //set up scaling
        float rx = Screen.width / native_width;
        float ry = Screen.height / native_height;

        GUI.matrix = Matrix4x4.TRS (new Vector3(0, 0, 0), Quaternion.identity, new Vector3 (rx, ry, 1));

        Rect mButtonRect = new Rect(1920-215,5,210,110);
        GUIStyle myTextStyle = new GUIStyle(GUI.skin.textField);
        myTextStyle.fontSize = 50;
        myTextStyle.richText=true;

        GUI.DrawTexture(new Rect(5,1080- 115,350,110),LogoTexture); 
        GUI.DrawTexture (new Rect (1530, 970, 350, 110), MobiliyaTexture);


        if (!btntexture) // This is the button that triggers AR and UI camera On/Off
        {
            Debug.LogError("Please assign a texture on the inspector");
            return;
        }

        if (mShowGUIButton) {

            GUI.Label(new Rect(40, 25, 350, 70), "<b> G E  9 1 0 0 C </b>",myTextStyle);

            //GUI.Box (new Rect (0,0,100,50), "Top-left");
            //GUI.Box (new Rect (1920 - 100,0,100,50), "Top-right");
            //GUI.Box (new Rect (0,1080- 50,100,50), "Bottom-left");
            //GUI.Box (new Rect (Screen.width - 100,Screen.height - 50,100,50), "Bottom right");

            // draw the GUI button
            if (GUI.Button(mButtonRect, btntexture)) {
                // do something on button click 
                OpenVideoActivity();
            }
        }
    }

    public void OpenVideoActivity()
    {
        var androidJC = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
        var jo = androidJC.GetStatic<AndroidJavaObject>("currentActivity");
        // Accessing the class to call a static method on it
        var jc = new AndroidJavaClass("com.mobiliya.gepoc.StartVideoActivity");
        // Calling a Call method to which the current activity is passed
        jc.CallStatic("Call", jo);
    }

}