Programatically Run Motive.io Script in Unity 3D
Tags: ar, geolocation, motiveio, unity
Published: 2018-03-26 20:00:42

---
title: Programatically Run Motive.io Script in Unity 3D
published: true
tags: ar,geolocation,motive.io,unity
canonical_url: 
---

<amp-img on="tap:lightbox" role="button" tabindex="0" width="701" height="198" layout="responsive" src="/assets/img/motive-io-logo-black-mobile.png"></amp-img>

> [Motive.io](https://www.motive.io) is a professional platform that allows you to integrate cutting-edge AR technology into compelling location-AR games and experiences.

[Motive.io](https://www.motive.io) is like **Wordpress** for geolocation game for Unity 3D featuring a set of tools that allow **authoring scripts** on their web-based interface and activate them on client.

<amp-youtube data-videoid="w_is8A8fLzk" width="480" height="270" layout="responsive"></amp-youtube>

The thing is, [Motive.io](https://www.motive.io) is only responsible for **hosting** the scripts, all the logics are actually ran offline on client based on conditions setup on authouring tool. That is fine for simple single-player games, but for more complex features like multiplayer, you need to be able to control your scripts **programmatically** , to be aware of their **events** and feeding them **parameters** from your own server.

Unfortunately, the service is currently in beta, _“launching public access to the platform on March 21st.”,_ the manual is lacking a lot of contents, the examples only scratch the surface, and there are **no SDK documenation**. Luckyly, their support is really fast and helpful.

> In this series, I will explain how to launch a script programmatically with dyanmic variables.

* * *

# Anatomy of a Motive Script

Motive script is created on [Motive.io](https://www.motive.io) Authoring tool.

<amp-img on="tap:lightbox" role="button" tabindex="0" width="1933" height="1093" layout="responsive" src="/assets/img/scripts-1.png"></amp-img>

Normally, you will be using a `Main` script to launch other scripts, and in example projects, there is a Scripts panel where you can manually activate them. However, if you are programmatically launching a script, you will need it’s **unique identifier**. Each script has one that can be found on the address bar at `scriptId` parameter.

<amp-img on="tap:lightbox" role="button" tabindex="0" width="583" height="91" layout="responsive" src="/assets/img/motive-find-script-id.PNG"></amp-img>

I think the term _“launching a script”_ is a little bit misleading. In fact, you will be creating instances of that script, each with an unique `runId` specified by you. Each instance has its own memory. For example: If you create instances of a `Location Task`, each instance will have its own location, status of completion, etc.

* * *

# Operations on Motive Script

There are 3 operation on a script instance you can do: **Launch, Stop and Reset.**

- **Launch:** creates a new script instance or resume the instance if it is already created
- **Reset:** halt the script and reset the original state of the script.
- **Stop:** halt the script, hide any location marker, but does not reset anything.

To understand the difference between **Reset** and **Stop** , consider this example:

- An instance of a script that contains **two location tasks** is launched.
- The player has already **completed one task** in that instance.
- If you **Stop** and then **Launch** the instance again, you will only see **the task that is not completed.**
- If you **Reset** and then **Launch** the instance again, you will see **both tasks.**

* * *

# ScriptManager Singleton

Script managing and operation is handle by a `ScriptManager` singleton with two main methods `LaunchScript` and `StopRunningScript`. Their most basic signatures are as follow:

```
public void LaunchScript(
  string scriptId, string runId, Action<bool> onComplete
);

public void StopRunningScript(
  string scriptId, string runId, bool resetState, Action onComplete
);
```

Both of them recieves `scriptId` for identifying the script, `runId` for identifying the script instance and `onComplete` Action for callback on completion.

- For **launching a new instance** of a script with `runId` as unique identifier, or **resuming an instance** with that id, we use:

```
ScriptManager.Instance.LaunchScript(scriptId, runId, onComplete);
```

- To **stop an instance** with id `runId`, we call `StopRunningScript` with `resetState = false`:

```
ScriptManager.Instance.StopRunningScript(scriptId, runId, false, onComplete);
```

- To **reset an instance** with id `runId`, we call `StopRunningScript` with `resetState = true`:

```
ScriptManager.Instance.StopRunningScript(scriptId, runId, true, onComplete);
```

* * *

# Try in Example

Start with the GhostHunter Unity template provided by [Motive.io](https://www.motive.io), we will be editting the script launcher to **launch new instance everytime**.

<amp-img on="tap:lightbox" role="button" tabindex="0" width="1280" height="720" layout="responsive" src="/assets/img/motiveghosthunter.jpg"></amp-img>

By default, the script launcher of the template only **launch and manage one instance** with `runId="test"` for each script.

```
// TestScriptsPanel.cs
ScriptManager.Instance.LaunchScript(e.Script.Id, "test", null);
```

If you run the project, each time you launch a script, the `Launch` button is turned in to a red `Stop` button. You can remove this behaviour by changing the logic of `TestScriptItem.cs` like this:

```
// TestScriptItem.cs
public void UpdateState()
{
  var isRunning = false; // Previously = ScriptManager.Instance.IsScriptRunning(m_script, "test");

  LaunchButton.gameObject.SetActive(!isRunning);
  StopButton.gameObject.SetActive(isRunning);
}
```

<amp-img on="tap:lightbox" role="button" tabindex="0" width="1137" height="566" layout="responsive" src="/assets/img/Screen%20Shot%202018-03-19%20at%204.11.01%20PM.png"></amp-img>

However, this only keep the `Launch` button, but this button wouldn’t create new script instance and **no new location marker** will be added. Instead, you would want to replace `"test"` with a **random identifier** like this:

```
// TestScriptsPanel.cs
var runId = System.Guid.NewGuid().ToString();

ScriptManager.Instance.LaunchScript(e.Script.Id, runId, null);
```

Now, you can run the project and launch any script and new instance of it would be initiated. Managing all of these instances would requires more coding since `TestScriptItem.cs` only track `runId = test` instances. We wouldn’t discuss that here, instead, let’s explore how to **add dynamic varibable** to our scripts.

* * *

# What’s next?

In the next post in this series, I will explain how to create dynamic variables in [Motive.io](https://motive.io) Authoring Tool and passing values to those variables when launching script instance in Unity 3D.