Building an app with Targets

Marker-based AR

Welcome to this tutorial. Here we are going through all necessary steps to create a native app for Android / iOS that makes use of Onirix’s Targets technology. The goal of this tutorial is to create an app that runs on your AR compatible device and allows us to place AR content on top of an image (functioning as a marker).

Setup and Tools

Let's go over the tools we are going to need.

  1. Onirix Studio: the web platform that is the base/starting point for all our AR projects.
  2. Unity is the most popular and widely used 3D engine for mobile applications. Unity is cross-platform, which allows developers to deploy the same app on multiple platforms.
  3. Onirix SDK in its mobile version, allows us to create Targets-type apps.
  4. XCode (for iOS export only).
  5. Full code available on Github.

Step 1: Create a new Targets project

We will start by creating a new project in the studio. In this Getting Started video you can see how to create your first project in Onirix. Inside the project we create a new Target, and use the scene editor to place our first 3D model. Unlike with surface targets, marker targets requires uploading an image that our app will seek for to place the target when found.

You can find the marker used in the video example here, and the 3D model [here].(https://sketchfab.com/models/6358bb3b52f74103bc2ad317e232ae52).

Take a look to our Scene editor page if you want to know more about it.

Step 2: Unity platform

The next step is to download Unity and create a new project. When opening Unity, a window appears. Make sure you run at least version 2018.2.7. To create a new project in Unity, go to the projects tab, and click on New project. Give it a name, left all other options by default and create. It may take several seconds to initialize.

Create project in Unity

Step 3: Onirix SDK

The next step is to download the Onirix SDK. For this we access the Onirix Mobile SDK repository on GitHub and download the latest release (Unity Package), which allows us to create Onirix Targets projects (place virtual content over images or any surface).

A double click on the downloaded package will start the import process to Unity. Unity will show you all the contents of the package.

Onirix sdk import screen We leave everything selected and click on Import. This completed the inclusion of the Onirix SDK in our project.

Step 4: Creating the App

At this point, you have two alternatives for creating your own app: using the OnirixScene provided with the SDK or build your application from scratch. While the latter option might be more appropriate in case you plan to customize all the elements of the application, the first provides a convenient and quick way to start developing your app, and should be more than enough for most cases. We strongly recommend that you choose this option, at least until you are familiar with the development with Onirix.

So start by dragging the OnirixScene into your hierarchy. After that, you can safely delete the SampleScene that Unity creates by default.

In this scene you will see that there is an object called Onirix containing all the necessary scripts for the development of Targets based applications. If you execute this scene you will notice that it is a functional application that displays the Onirix logo and responds to the user's interactions by changing the background color when the screen is touched. Nothing impresive or AR related, but it is a starting point. We will delete the "Onirix Default Controller", the "Onirix UI Manager" and the "Onirix Touch Manager" scripts from the Onirix object since we will not use them in this example. To do so, we will click on the gear icon and select option Remove Component for all of them.

The purpose of the remaining scripts is described below.

  • OnirixAuthManager: Owns the Project Token that must be used for authentication in every interaction with the Onirix Studio REST API.
  • OnirixAssetLoader: The OnirixAssetLoader is responsible for loading Targets and Spaces.
  • OnirixDynamicLoader: Allows you to download and show Targets on demand, displaying a placeholder object during the loading process.
  • OnirixMobileManager: Works as an abstraction layer from both the ARCore and ARKit frameworks, providing the surface and marker detection features.

Step 5: Adding your App logic

Right-click on the folder you have chosen for containing your app scripts and select Create ➡ C# Script. Rename the NewBehaviourScript to MainController and double-click on it to open it with your preferred text editor.

The UI screen that we will design must have a label to show status messages (this time we will not need a button because the target will be instantiated automatically when the marker is detected). We will declare it with the SerializeField attribute to bind it to the pertinent object later from the inspector.

[SerializeField] private Text _statusText;

Remember that UnityEngine.UI must be imported for the use of the Text class.

Then, we will add this script as Component to the Onirix scene object to ensure that it will be executed when the scene is loaded. The field marked as SerializeField will be now available from the inspector.

For the design of the screen, we will instantiate a Canvas object in the hierarchy and then we will set the desired reference resolution (1920x1080 seems ok). We will then add a Text as child object, setting its desired size and alignment. We will also replace its displayed text to "Scan the marker to see the mockup".

Once you are done with the design, you will be able to bind the UI with the MainController SerializedFields from the inspector.

At this point, since our MainController inherits from MonoBehavior, we can implement the Start method to define how it will behave when the application starts. The first thing we will do is preventing the screen from entering to energy saving mode.

Screen.sleepTimeout = SleepTimeout.NeverSleep;

Next, we will initialize the OnirixDynamicLoader using the Init method, to which we can optionally pass an IDynamicLoadListener to receive loading events. We will make our own MainController script to implement this interface, so we will use this as parameter.

OnirixDynamicLoader.Instance.Init(this);

The class declaration line will look like the following.

public class MainController : MonoBehaviour, IDynamicLoadListener 

Then we will have to implement the methods of this interface, in each one of which we will change the message for our text label.

public void OnTargetAssetsDownloaded(Target target)
{
    _statusText.text = "Assets downloaded";
}

public void OnTargetAssetsLoaded(Target target)
{
    _statusText.text = "Assets loaded";
}

public void OnTargetAssetsStartDownloading(Target target)
{
    _statusText.text = "Downloading assets";
}

public void OnTargetAssetsStartLoading(Target target)
{
    _statusText.text = "Loading assets";
}

Then we must start the marker detection, but we must wait for the OnirixMobileManager to be initialized before. For this purpose, we will implement an auxiliary method that will be launched as Coroutine and that will invoke the passed callback when it is ready.

private IEnumerator WaitForAR(System.Action onReady)
{
    yield return new WaitUntil(() => OnirixMobileManager.Instance.IsReady);
    onReady();
}

Once the OnirixMobileManager is ready we can start to deal with the marker detection. We will call the StartMarkerDetection method of the MobileManager that receives a callback indicating when a marker has been detected. In this callbacks we will load the detected Target (whose oid is provided as parameter), change the message on the label, and hide the crosshair. The complete code for the OnirixMobileManager startup and the marker detection callback is shown below.

StartCoroutine
(
    WaitForAR
    (
        () =>
        {
            OnirixMobileManager.Instance.StartTargetDetection
            (
                (targetOid) =>
                {
                    // Hide the default crosshair
                    OnirixMobileManager.Instance.HideCrosshair();

                    // When a marker is detected. Let's load it's assets .
                    _statusText.text = string.Format("Loading target {0}, please wait ...", targetOid);
                    OnirixDynamicLoader.Instance.LoadTarget(detectedTarget);
                }
            );
        }
    )
);

Step 6: Linking your App with Onirix Studio

Link your app with Onirix Studio is pretty straightforward. We have just to fill the required inspector field for the OnirixAuthManager script with the appropiate information.

From the Project List on the Onirix Studio web interface we can copy to clipboard the Project Token by clicking on the three dots icon at the top-right corner of our project entry and pressing the Copy button. We can now paste them in the corresponding inspector field for the OnirixAuthManager script.

Ta-da! Our application is now linked with Onirix Studio.

Step 7: Exporting the App

Our project is finally completed and this tutorial is reaching its end. We have just to apply a few settings to get our app working on both Android and iOS devices at last.

The first task is common both for Android and iOS. We need to open the Unity graphics settings for our project by clicking on Edit ➡ Project settings ➡ Graphics. Then we have to go all the way down until we reach the Shader Preloading section. We have to set the size of the Preloaded shaders to 1, filling the slot with the OnirixGLTFShaderVariants.

Exporting to Android devices

To export specifically for Android devices you have first to open the Build Settings (File ➡ Build Settings), select Android as Target on the list, and then press the Switch platform button. The switch platform process will take a while, so be patient.

Once this process has finished, open the Player Settings by clicking on the corresponding button on this window. Write your app and company name of your choice and then check the following:

  • XR section
    • Check the ARCore supported checkbox.
  • Other settings
    • Uncheck the Multithreaded Rendering checkbox.
    • Write the package name of your choice.
    • Set Android 7.0 ‘Nougat’ (API level 24) as Minimum API Level.
    • Set Automatic (highest installed) for the Target API Level.
    • Choose .NET 2.0 instead of .NET 2.0 Subset as API Compatibility Level.
    • Check the Allow ‘unsafe’ Code checkbox.
  • Publishing settings
    • Optionally, you can specify the keystore of your choice and fill the signing information if you want to perform a release build.

Now we are ready to deploy our app by pressing on the Build button on the Build Settings window (or Build & Run if we want to both generate the APK file and install it on any connected Android device).

Exporting to iOS devices

To export specifically for iOS devices you have first to open the Build Settings (File ➡ Build Settings), select iOS as Target on the list, and then press the Switch platform button. The switch platform process will take a while, so be patient.

Once this process has finished, open the Player Settings by clicking on the corresponding button on this window. Write your app and company name of your choice and then check the following:

  • Other settings
    • Write the package name of your choice.
    • Choose .NET 2.0 instead of .NET 2.0 Subset as API Compatibility Level.
    • Write 11.0 as Target Minimum iOS Version.
    • Checks the Requires ARKit support checkbox.
    • Check the Allow ‘unsafe’ Code checkbox.

Now we are ready to deploy our app by pressing on the Build or Build & Run button. Unity will ask you to choose a folder in your computer to export all your code building a new XCode project with it. Of course, you will need to provide a valid provisioning profile in order to sign your app and deploy it on your iOS device. If you don’t know how to do this, please check the related Apple documentation.


If you are reading this, you probably have your own Hello World Markers app on your mobile device at this point. In that case: congratulations! You have successfully followed this tutorial.

If unfortunately it is not like that, write us to our support email with your questions. We are always willing to help you.