Unity 3D Plugin >
Cloud Planar Marker

This tutorial will guide you through the creation of a simple AR application that detects and tracks an image marker downloaded from our cloud service and draws a simple 3D model on it. Our SDK is designed to work with Unity3D 5+ and support both iOS and Android.

First launch Unity3D and create a new project.

Name your project (i.e. PikkartARTutorial) and choose the project directory then click the Create project Button.

Once the project is created in the Editor select File/Build Settings... (or press Ctrl + Shift + B).
In this window select Android and click Switch Platform (for instructions on how to set-up the project for iOS see the previous tutorial).

Then click on Player Settings... On the inspector set the Minimum API Level to 15 and set the Write Access to External.

If you have already purchased a license, set the Bundle Identifier to the package name you provided when buying your Pikkart AR license, otherwise use "com.pikkart.trial".

You MUST download the license file from our site (even for the trial identifier) as described in the Cloud Manager guide and put it into the StreamingAssets folder of your Unity3D project.

The license comes in Android or iOS variants, use the correct one accordingly.

Now you have to import the PikkartAR package in your project. To do that select Assets/Import Package/Custom Package... and select the Unity sdk file from <pikkart_sdk_dir>/Unity/PikkartAR.unitypackage. When the list of components appears click Import

Now we are ready to set up the AR scene. Select File/New Scene (Ctrl + N) and save it with File/Save Scene (Ctrl + S).

Delete the Main Camera, the Directional Light and all the objects in the scene Hierarchy. From the PikkartAR/Prefabs folder, add the PikkartARCamera prefab to the scene (drag and drop it in the hierarchy). Into the inspector, under MainScript, change Recognition Storage to GLOBAL and Recognition Mode to TAP_TO_SCAN (this is the only recognition mode working for global recognition). This way each call to the StartRecognition method starts a single small burst of calls to our cloud recognition service. Then click Add a Database and type the code of the cloud database you created previously.

The easiest way to use a cloud marker is to add the CloudMarker prefab (PikkartAR/Prefabs folder) to the scene. In the inspector, in the CloudMarkerObject script, specify the CloudMarkerId you want to show (you can find the ids of your cloud markers on the control panel of your marker database dashboard). Remember not to use as marker one an image that is also present in your app assets as local marker!

The augmented content linked to this marker must be placed in the hierarchy as a child of the CloudMarker. In this tutorial we use the SuperPikkart_blue prefab from our sample package (Samples/Prefabs).

Now start the application, select File/Build Settings… and click Add Open Scenes to add the current scene to the build. Connect an android device with developer option enabled and click Build And Run. Remember to print a physical copy of the marker!

If you want additional control over the augmented content of your cloud markers you can use the custom data field. In this tutorial we will put a json object inside the custom data to tell the app what to show when the marker is found. This json string will have two fields: a shape and a color:

{
    "shape":"sphere",
    "color":[255,255,0]
}

Create a CustomDataDTO script to deserialize this data into.
 

using UnityEngine;
using System.Collections;

public class CustomDataDTO {
    public string shape { get; set; }
    public int[] color { get; set; }
}

Now create a CloudRecognitionListener script that implements the ICloudRecognition interface.

using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using PikkartAR;

public class CloudRecognitionListener : ICloudMarkerObjectListener 
{
    public void OnCloudMarkerFound (MarkerInfo marker) {
    }

    public void OnCloudMarkerLost (MarkerInfo marker) {
    }
}

The interface has two methods, the first is called whenever a cloud marker is found, the second is called when a marker is lost. You can access all the informations about the marker in the MarkerInfo object.
Now create a dictionary to store every marker found and the GameObject that will be associated with it.

private Dictionary<string, GameObject> cloudMarkerList = new Dictionary<string, GameObject>();

Inside OnCloudMarkerFound we will check if the marker has been already found, if not we create the augmented content for it and add it to the dictionary. First we need to deserialize the json object in the DTO:

CustomDataDTO customData = JsonUtilities.ToObject<CustomDataDTO> (marker.getCustomData ());

With a switch/case instantiate the type of shape associated with the marker. Then we scale down the object and place it at the center of the marker.

GameObject gameobject;
switch (customData.shape) {
    case "sphere":
        gameobject = GameObject.CreatePrimitive (PrimitiveType.Sphere);
        break;
    case "cube":
        gameobject = GameObject.CreatePrimitive (PrimitiveType.Cube);
        break;
    default:
    return;
    break;
}
gameobject.transform.localScale = new Vector3 (.4f, .4f, .4f);
gameobject.transform.position = new Vector3 ((float)-marker.getWidth() /2, 0f, (float) marker.getHeight() /2);

To apply the desired color to the 3D object create a new material, change its color and then assign it to the object MeshRenderer.

var material = new Material(Shader.Find("Diffuse"));
material.color = new Color (customData.color [0], customData.color [1], customData.color [2]);
gameobject.GetComponent<MeshRenderer>().material = material;

Now that the object is all set, we can add it to the dictionary.

cloudMarkerList.Add (marker.getId (), gameobject);

In the end of OnCloudMarkerFound set the gameObject as active so it will be rendered on the device screen.

cloudMarkerList [marker.getId ()].SetActive (true);

The whole function should look like this:

public void OnCloudMarkerFound (MarkerInfo marker)ì>
{
    if (!cloudMarkerList.ContainsKey (marker.getId ())) {
        CustomDataDTO customData = JsonUtilities.ToObject<CustomDataDTO> (marker.getCustomData ());
        GameObject gameobject;
        switch (customData.shape) {
            case "sphere":
                gameobject = GameObject.CreatePrimitive (PrimitiveType.Sphere);
            break;
            case "cube":
                gameobject = GameObject.CreatePrimitive (PrimitiveType.Cube);
            break;
            default:
                return;
            break;
        }
        gameobject.transform.localScale = new Vector3 (.4f, .4f, .4f);<
        gameobject.transform.position = new Vector3 ((float)-marker.getWidth() /2, 0f, (float) marker.getHeight() /2);

        var material = new Material(Shader.Find("Diffuse"));
        material.color = new Color (customData.color [0], customData.color [1], customData.color [2]);
        gameobject.GetComponent<MeshRenderer>().material = material;

        cloudMarkerList.Add (marker.getId (), gameobject);
    }
    cloudMarkerList [marker.getId ()].SetActive (true);
}

The only thing the OnCloudMarkerLost has to do is to deactivate the gameobject associated with the marker that is just being lost.

public void OnCloudMarkerLost (MarkerInfo marker)
{
    if (cloudMarkerList.ContainsKey (marker.getId ())) {   
		cloudMarkerList [marker.getId ()].SetActive (false);

    }
}

The CloudRecognitionListener is completed. In the MainScript, just after the initialization, instantiate and set the CloudRecognitionListener as the default CloudMarkerObjectListener for the Recognition Manager. Please note that if you change the default CloudRecognitionListener the CloudMarker prefab will no longer work.

public class MainScript : PikkartMain, IRecognitionListener
{
    private void Start()
    {
        InitRecognition();
        SetCloudMarkerObjectListener (new CloudRecognitionListener ());
        StartRecognition(_recognitionOptions, this);
}

Now start the application, select File/Build Settings... and click Add Open Scenes to add the current scene to the build. Connect an android device with developer options enabled and click Build And Run. Remember to print a physical copy of the marker! The end result of our tutorial should look like this when tracking the cloud marker: