Scripting

Although you don't need to write code to build advanced effects, we've included a powerful scripting framework that you can use to build more immersive, customized and complex augmented reality experiences.

You can use scripting to:

  • Trigger audio and animations
  • Make effects interactive based on taps or facial movements
  • Script 3D and 2D animations, including path-drawing animations
  • Initiate network requests to fetch outside data and textures
  • Accept data passed in from a camera share request

AR Studio uses a reactive scripting model in JavaScript to create relationships between objects, assets and values. This means you don't have to execute code frame-by-frame to animate art, look for user input or realign a mask to a face.

Reference Documentation

Learn more about the reactive scripting modules available in the Reference Documentation.

Adding Scripts

To add a script to your project:

  1. Go to the Assets panel and click +
  2. Select Create New Script
  3. Double-click on script.js in the Assets panel
  4. Write the script in the script editor on your computer
  5. Save and close it

Please make sure that you test and debug your script. It is recommended that ES5 should be used when writing scripts. This is to ensure your effect's scripted behavior functions on all devices.

Reactive Programming

AR Studio uses a reactive programming model, which is compatible with visual programming, makes writing correct scripts simpler than in an immediate programming model and improves performance by reducing the frequency of calls made into the scripting engine.

One of the key ways in which reactive programming helps to improve performance is that it lets you treat scalar values as signals. A signal is a special object containing a value that changes over time. When signals are bound to variables, changes to the values are propagated in native code, eliminating the need for a context switch into the scripting engine.

Transitioning from imperative programming into reactive programming requires you to shift the way that you think, because of how values are propagated through your program. For example, consider this code:

y = 2x + 4;

With imperative programming, the value of y is set when the method is executed. As the value of x changes, y remains the same. The value of y is only changed when a new value is assigned to it. When we consider the AR Studio scripting environment, it's clear that the values you'll be monitoring are probably changes in the position or orientation of world objects (like a face). With this model, if you wanted to move an object in response to facial movements, you'd need to write script to modify the related values and have it run after each frame. Application performance would suffer as a result.

With reactive programming, we bind the value of y to the result of the equation. When the value of x changes, a signal is generated. The signal causes the value of y to be updated. All of this signaling and updating happens in native code, as opposed to a script, so it has a minimal impact on application performance. With this model, when facial position or rotation value is a signal bound to a property of a world object, the world object is automatically updated when the face moves.

Binding

In JavaScript, the following statement represents an assignment:

// A scene object's transform is updated to a new value
someObject.transform.x = Animation.animate(driver, sampler.x);

However, when the object at the root of the expression (the lvalue) is a Reactive object, this statement is not a simple assignment, but rather, a binding. This means:

  • The r value can't be a simple scalar or string, but must be a ScalarSignal or StringSignal.
  • Rather than assigning a value, you're binding the signal to that property. When the value underlying the signal is updated, so is the value of the property.

This means that rather than programming in the usual imperative style, where you use conditional logic to control the flow of data through a program and perform an assignment every time you need it, you're programming in a declarative style.

You declare signal paths, binding signals to properties and let the framework do the work of shuttling data around for you. You still have conditionals for flow control within these signal paths, but they are part of the signal path, not statements surrounding the signal path (as in the case of an imperative if-else or switch statement).

If these concepts are new to you, the function code below should help to clarify them.

Converting Values to Signals

The following code demonstrates how to assign numeric or string values to the properties of a Reactive object:

var Reactive = require('Reactive');
var Diagnostics = require('Diagnostics');

function init() {
var aScalar = 5;
var aString = 'hello';
var aBool = true;
Diagnostics.log(aScalar);
Diagnostics.log(Reactive.val(aScalar));
Diagnostics.log(aString);
Diagnostics.log(Reactive.val(aString));
Diagnostics.log(aBool);
Diagnostics.log(Reactive.val(aBool));
}

init();

This code gives the following Console output:

>> 5
>> ScalarSignal {
Methods:
trigger
interval
... more methods ...
}
>> hello
>> StringSignal {
Methods:
concat
eq
... more methods ...
}
>> true
>> BoolSignal {
Methods:
ifThenElse
xor
... more methods ...
}

The Reactive.val() function causes a JavaScript numeric, string, or Boolean type to be converted to a ScalarSignal, StringSignal or BoolSignal object that may be bound to a property of a Reactive object.

Keep in mind that in most cases, constants are implicitly converted into signals. You should only need to use Reactive.val() as a fallback option.

Signal Binding

Some objects have properties that use signals to define the location coordinates and rotation angles. Signals are special objects with values that change over time. This video shows you how you can bind the signals from a source object to move a target object.

Something Went Wrong
We're having trouble playing this video.

Monitoring Signals

You can use the Diagnostics.watch function to add specific signals to the watch view in AR Studio.