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.

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:

Importing textures to the unfinished project

If you want to import your own textures, you must 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.

Adding

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

Editing

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:

Scripting

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.
  • Select Capabilities.
  • Click +.
  • 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

Include the NativeUI and Textures modules.

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

Access the textures using the get method.

The string passed into the get method should be the name of the texture in the Assets panel.

          const texture0 = Textures.get('texture0');
          const texture1 = Textures.get('texture1');
          const texture2 = Textures.get('texture2');          
        

Create a reference to the picker.

          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.

          const index = 0;

          const configuration = { 

          selectedIndex: index,

          items: [ 
          {image_texture: texture0}, 
          {image_texture: texture1}, 
          {image_texture: texture2} 
          ]

          };
        

Configure the picker.

          picker.configure(configuration);
        

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
          }); 
        

Example

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.

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

          const plane = Scene.root.find('plane0'); 

          const texture0 = Textures.get('texture0'); 
          const texture1 = Textures.get('texture1'); 
          const texture2 = Textures.get('texture2'); 

          const picker = NativeUI.picker; 

          const index = 0; 

          const configuration = { 

          selectedIndex: index, 

          items: [ 
          {image_texture: texture0}, 
          {image_texture: texture1}, 
          {image_texture: texture2}, 
          {image_texture: texture0}, 
          {image_texture: texture1},
          {image_texture: texture2}, 
          {image_texture: texture0}, 
          {image_texture: texture1}, 
          {image_texture: texture2} 
          ]

          };

          picker.configure(configuration);
          picker.visible = true;

          picker.selectedIndex.monitor().subscribe(function(index) {
          plane.material.diffuse = configuration.items[index.newValue].image_texture;
          });  
        

More information on the Picker class can be found here.

Was this article helpful?