Adding the Native UI Picker

The native UI picker is an interface that can be added to Spark AR effects. It lets people choose different options by tapping icons on the screen.

The final effect in this tutorial lets the user tap different icons on the device screen to change the emojis shown in the effect. The sample content includes the textures you'll need to follow this tutorial - you could replace these with your own instead.

You can create this effect using either the Picker UI patch or with scripting. We’ve included both options in this tutorial.

Download the sample content to follow along. It includes both the finished and unfinished versions of the project created with the Patch Editor.

The unfinished project

In the unfinished project we’ve used a face tracker and Eyelid patch to position two planes over the user’s eyelids and applied a flower emoji texture to both planes.

We’ve also imported five different emoji textures, listed in the Assets panel as Emoji_1 to Emoji_5:

Using your own textures

To import your own textures to use instead of the sample content, at the bottom of the Assets panel simply click + Add Asset then Import from Computer.... Then, select the textures you want to import from your computer.

You'll need to edit the compression settings. To do so:

  1. In the the Assets panel, select the texture.
  2. In the Inspector, check the box next to No compression:

Using the patch editor

In this effect, we’ll use the Patch Editor to match the texture covering the eyelids to the texture of the picker icon selected by the user.

First create a patch representing this texture. To do so:

  1. Select material0 in the Assets panel.
  2. In the Inspector, click the arrow to the left of the Texture, currently set to Emoji_1.

Your graph will look like this:

Adding and editing the Picker UI patch

We’ll use the Picker UI patch to display the icons the user can choose between and trigger the update to the texture.


First add the Picker UI patch by right-clicking in the Patch Editor and selecting Picker UI:


To display the picker interface and trigger updates to the icons, edit the Picker UI patch as follows:

  1. Check the box to the right of the Visible port, to display the picker interface on the user’s screen.
  2. In each dropdown box to the right of the Texture 1-5 ports, select a different texture from Emoji_1 - Emoji_5.
  3. To the right of Start Index, enter 0. This will set to set the flower emoji as the texture covering the eyelids when the effect starts.

Your graph will look like this:

The picker interface will now be visible in the Simulator:

Finally, connect the Selected Texture output of the Picker UI patch to the Diffuse Texture patch. This will trigger the update to the texture option each time the user selects an icon.

Your final graph will look like this:


You can also achieve this final effect using scripting. There is no sample project to follow and it's a good idea to take a look at our guide to scripting if it's something you're new to.

Add the capabilities you need

Add the Picker UI: under Native UI Control.

To do this:

  • Go to Project in the menu bar and select Edit Properties.
  • Select the Capabilities tab and click on the + to add a new capability.
  • Search for Native UI Control, and click Insert.

Native UI Control will now be listed as a capability. Next:

  1. Click the arrow to the left of Native UI Control to reveal a list of options underneath it.
  2. Check the box next to Picker.

Not all capabilities are added to projects automatically. If you need other capabilities you may need to add them manually.

Now you're ready to create a new script, and open it.

The Script

Load in the NativeUI and Textures modules so that you can use their APIs.

 const NativeUI = require('NativeUI'); 
 const Textures = require('Textures');

Access the textures using the findFirst() method exposed by the TexturesModule API. The string passed into the method should match the name of the textures in the Assets panel.

You can wrap these method calls in a Promise.all() if you are accessing multiple objects.

 // Access the textures with the names texture0, texture1 and texture2 from the Assets panel
 const [tex0, tex1, tex2] = await Promise.all([

Create a reference to the picker object.

 const picker = NativeUI.picker;

Set up the configuration for the picker. The configuration consists of a selectedIndex and items.

The selectedIndex is an optional parameter that specifies the item that will be selected by default, this will be 0 (the first item) if none is specified.

The items are a list of textures to be used in the picker. Only uncompressed textures are supported.

 const configuration = { 

     selectedIndex: 0,         
     items: [
         {image_texture: texture0}, 
         {image_texture: texture1}, 
         {image_texture: texture2}

Configure the picker with the configuration you set up.


Set the picker's visibility to true. This property is false by default and needs to be set to true in order to show the picker.

 picker.visible = true;

Subscribing to the selectedIndex property of the picker can be used to determine when a new item has been selected.

 picker.selectedIndex.monitor().subscribe(function(index) { 
     index.newValue // The new selectedIndex value


The example below shows how this can be used to set the diffuse texture of a material assigned to a plane, to that of the selected picker item. This is done using the diffuse property of the MaterialBase class.

This example also highlights the ability to add the same texture to the picker more than once.

// Load in the required modules
const NativeUI = require('NativeUI');
const Textures = require('Textures');
const Materials = require('Materials');

// Enables async/await in JS [part 1]
(async function() {

    //  Access the material and textures from the Assets panel
    const [planeMaterial, tex0, tex1, tex2] = await Promise.all([

    // Create a picker object
    const picker = NativeUI.picker;

    // Set up the picker configuration
    const configuration = {
        selectedIndex: 0,
        items: [
            {image_texture: tex0},
            {image_texture: tex1},
            {image_texture: tex2}

    // Configure the picker with the configuration

    // Set the picker to be visible
    picker.visible = true;

    // Monitor when a new item in the picker is selected
    picker.selectedIndex.monitor().subscribe(function(index) {

        // Set the plane material's diffuse texture to the associated texture from the picker
        planeMaterial.diffuse = configuration.items[index.newValue].image_texture;

// Enables async/await in JS [part 2]

More information on the Picker class can be found here.

Was this article helpful?