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.
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:
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:
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:
Your graph will look like this:
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:
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:
Native UI Control will now be listed as a capability. Next:
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.
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 });
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.
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.