Adding the Native UI Picker

The user is shown with flowers over their eyes.

The native UI picker is an interface that can be added to Meta Spark 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:

The material and textures are shown in the Assets panel.

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 +, 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 Assets panel select the texture and go to the Compression section of the Inspector.
  2. To the right of each device type (iOS, Android, Older Android), select None from the dropdown.

Setting the compression to 'None'.

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:

A patch graph containing 7 patches.

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:

A patch graph containing 2 patches, the Picker UI patch and a patch representing the material's texture.

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:

Our textures have been added to the Picker UI patch.

The picker interface will now be visible in the Simulator:

The picker UI can be seen 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:

A patch graph containing 2 patches.

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 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.

Adding the Native UI Control capability.

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

Create a reference to the picker object:

 const picker = NativeUI.picker;

The picker object needs to be configured with a list of uncompressed textures that will be displayed in the picker.

Use the findFirst() method exposed by the TexturesModule API to locate textures from the Assets panel. The string passed into the method should match the name of the texture as it appears in the project.

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

// Locate the textures from the Assets panel
const [tex0, tex1, tex2] = await Promise.all([
    Textures.findFirst('texture0'),
    Textures.findFirst('texture1'),
    Textures.findFirst('texture2')
]);
          

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 configuration = { 

     selectedIndex: 0,         
     items: [
         // The textures from a previous step
         {image_texture: tex0}, 
         {image_texture: tex1}, 
         {image_texture: tex2}
     ]
 };
        

Configure the picker with the configuration you set up:

 picker.configure(configuration);

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

 picker.visible = true;

Monitor changes to the picker's selectedIndex property by subscribing to the EventSource returned by calling the monitor() method on selectedIndex.

This is used to determine when a new item has been selected:

 picker.selectedIndex.monitor().subscribe(function(index) {           
     // 'index.newValue' contains the value of the
     // item currently selected in the picker
 });

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.

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

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

    // Create a reference to the NativeUI's picker object
    const picker = NativeUI.picker;
          
    //  Access the material and textures from the Assets panel
    const [planeMaterial, tex0, tex1, tex2] = await Promise.all([
        Materials.findFirst('material0'),
        Textures.findFirst('texture0'),
        Textures.findFirst('texture1'),
        Textures.findFirst('texture2')
    ]);

    // Set up the picker configuration
    // The 'tex1' texture is reused in this configuration
    const configuration = {
        selectedIndex: 0,
        items: [
            {image_texture: tex0},
            {image_texture: tex1},
            {image_texture: tex2},
            {image_texture: tex1}
        ]
    };

    // Configure the picker with the configuration
    picker.configure(configuration);

    // Display the picker
    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.

Using a template

To speed up the process of preparing a Native UI project, you can also use one of the templates available in the Meta Spark Welcome screen. The 2D and 3D Sticker templates both use the UI picker to control the visibility of objects.

The Meta Spark Studio welcome screen.