Building an app with Targets

AR with surface detection

Welcome to this tutorial. Here we are going through all necessary steps to build 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 3D content on a surface as part of an Augmented Reality scene.

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.

Follow this video from 0:33 to 1:45 and then continue reading. You can take a look to our Scene editor page if you want to know more about this.

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.

This script will hold the Target Oid referencing Onirix Studio. To be able to set this value from the inspector, instead having to set them as script constants, we will add to them the SerializeField attribute.

[SerializeField] private string _targetOid;

The UI screen that we will design must have a button that allows us to place the Target and a label to show status messages. From this script we will subscribe to the button events, and we will set the text of the label, so we need a reference to those components. We will declare them with the SerializeField attribute to bind them to the pertinent object later from the inspector.

[SerializeField] private Button _loadTargetButton;
[SerializeField] private Text _statusText;

Remember that UnityEngine.UI must be imported for the use of the Button and Text classes.

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 fields 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 Button and a Text as children objects, setting its desired size and alignment. We will also replace the text of the Button (in the child label object) to "Load Target" and the one of the Text object to "Look around to detect surfaces".

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. We will also take the opportunity to set the button initial status to not interactive.

Screen.sleepTimeout = SleepTimeout.NeverSleep;
_loadTargetButton.interactable = false;

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.


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 = "Target assets downloaded!";

public void OnTargetAssetsLoaded(Target target)
    _statusText.text = "Target assets loaded!";

public void OnTargetAssetsStartDownloading(Target target)
    _statusText.text = "Target assets started download!";

public void OnTargetAssetsStartLoading(Target target)
    _statusText.text = "Target assets started loading!";

Then we must start the surface 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);

Once the OnirixMobileManager is ready we can start to deal with the surface detection. We will call the StartSurfaceDetection method of the MobileManager. It receives two callbacks: the first indicates when a surface has been detected and the second tells us whether the surface was lost. In those callbacks we will show the relevant message on our Text label and enable or disable the Button as appropriate. The complete code for the OnirixMobileManager startup and the surface detection callbacks is shown below.

        () =>
                () =>
                    _statusText.text = "Click on the button to place the target";
                    _loadTargetButton.interactable = true;
                () =>
                    _statusText.text = "Move around to detect a surface";
                    _loadTargetButton.interactable = false;

Finally, we will code the behavior for the button, which will load the chosen Target, it will show a message on the label, disable the button and hide the crosshair.

_loadTargetButton.onClick.AddListener(() =>
    _statusText.text = "Loading target, please wait ...";
    _loadTargetButton.interactable = false;

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 fields for every 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 it on the corresponding inspector field for the OnirixAuthManager script.

Getting the Target Oid is just as simple. On the Onirix Studio web interface we will choose the desired target to enter the 3D target editor screen. There, in the property editor at the top right of the screen, we will see the oid for the chosen target and we will be able to copy it just by clicking on the button with two overlapping squares. We will paste it on the corresponding inspector field for our MainController 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 Surfaces app on your mobile device at this point. In that case: congratulations! You have successfully completed 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.