Make Things Change on Tap
FeaturedHey Everyone,
Let’s make something change on tap! In this guide we will go through an example of tapping to change objects, tapping to change sprite textures, and tapping to change material colors.
So in my current project, I have three objects that I want to tap through. In this example each item is an object with a MeshVisual component (3D object), but it can be anything, such as: a sprite, a parent of multiple , a billboard, etc..
First let’s create a box (Add new -> Mesh Visual -> Box) to define where a user’s tap would count and call it TouchCollision. Resize this box to roughly encompass our objects.
Although you can use any MeshVisual, including the actual object you’re displaying, it’s sometimes to have a seperate mesh since it can stay consistent across different objects and allow you to tap on non-MeshVisual object such as a sprite.
Since we don’t actually want to see the TouchCollision, let’s give it an invisible material. In the TouchCollision Inspector panel, under Mesh Visual component, click “Default” to open the material selection window. In this window, we can Add New “Unlit” material. Select the new Unlit material in the Resources panel and uncheck “‘Depth Test”, “Depth Write”, “Color Write”.
To use the TouchCollision, we’ll add a TouchComponent (Inspector Panel -> Add Component -> Touch) and assign the TouchCollision to it.
Next, let’s add a ScriptComponent (Inspector Panel -> Add Component -> Script) on the same object. This script will use theTouchComponent and iterate through our items when we tap. Add a new script to this component on ‘Initialize’.
Then let’s edit the script (double-click on the script in your Resources panel). To get references to our items in this script, we can create an input that takes in an array of SceneObject. Then in the Inspector Panel of TouchCollision, you can add our objects to the array--in this case item1, item2, item3.
// @input SceneObject[] items
Since we only want to see one object at a time, we can loop through our “items” array and disable everything but the first one.
// Arrays are indexed from 0.
// Disable everything but the first (0th) item
for (var i = 1; i < script.items.length; i++) {
script.items[i].enabled = false;
}
Below that, we tell the script that we want to activate the next item in the array when a TouchStartEvent happens.
function activateNextItem () {
// we’ll fill this in a second
}
// Bind the function to the touch event.
var touchEvent = script.createEvent("TapEvent");
touchEvent.bind(activateNextItem)
When activateNextItem gets called by the TapEvent, we want the Lens to disable the current item and enable the next item. To help us do this, we need to keep track of our current item.
// We remember what item is currently visible.
// When we start it’s the 0th item.
var currentItemIndex = 0;
// Define what happens when you tap.
function activateNextItem () {
// Disable the current item.
script.items[currentItemIndex].enabled = false;
// Increment the current item index
currentItemIndex += 1;
// We need the current item index to wrap around
// once it's higher than the number of items we have.
currentItemIndex = currentItemIndex % script.items.length;
// Enable the new item.
script.items[currentItemIndex].enabled = true;
}
And that’s it! In your preview you should be able to do this:
Our final script:
// @input SceneObject[] items
// Arrays are indexed from 0.
// Disable everything but the first (0th) item .
for (var i = 1; i < script.items.length; i++) {
script.items[i].enabled = false;
}
// We remember what item is currently visible.
// When we start it's the 0th item.
var currentItemIndex = 0;
// Define what happens when you tap.
function activateNextItem () {
// Disable the current item.
script.items[currentItemIndex].enabled = false;
// Increment the current item index
currentItemIndex += 1;
// We need the current item index to wrap around
// once it's higher than the number of items we have.
currentItemIndex = currentItemIndex % script.items.length;
// Enable the new item.
script.items[currentItemIndex].enabled = true;
}
// Bind the function to the touch event.
var touchEvent = script.createEvent("TapEvent");
touchEvent.bind(activateNextItem)
Bonus:
You can also use similar scripts to modify existing objects:
Instead of passing an array of objects, you can pass in an array of textures and then iterate through the textures on one sprite.
// @input Component.SpriteVisual sprite
// @input Asset.Texture[] textures
// Our starting texture index
var currentItemIndex = 0;
// Assign the initial texture to our sprite
script.sprite.mainPass.baseTex = script.textures[currentItemIndex]
// Define what happens when you tap.
function changeTexture () {
// Increment the current item index
currentItemIndex += 1;
// We need the current item index to wrap around
// once it's higher than the number of items we have.
currentItemIndex = currentItemIndex % script.textures.length;
// Change the sprite's texture
script.sprite.mainPass.baseTex = script.textures[currentItemIndex];
}
// Bind the function to the touch event.
var touchEvent = script.createEvent("TapEvent");
touchEvent.bind(changeTexture);
Or instead of passing any array, you can use script to get random results on tap!
// -----JS CODE-----
// @input SceneObject object
// Define what happens when you tap.
function changeColor () {
// Get the item's mesh visual
var meshVisual = script.object.getFirstComponent("Component.MeshVisual");
// Change it's baseColor
meshVisual.mainPass.baseColor = new vec4(Math.random(), Math.random(), Math.random(), 1.0);
}
// Bind the function to the touch event.
var touchEvent = script.createEvent("TapEvent");
touchEvent.bind(changeColor);
Happy crafting!
Hi! I want to change face mask on tap. I don't know much about scripting and all, maybe that's why I'm stuck. I have got eye color, color correction and mask grouped. I want to change all these at once when tap. As you can see I've made 3 groups exactly like that. Please HELP!
Hi Divya,
Are you not able to use the script above? You can set the objects to be turned off and on be "Neon Light", "Neon Lion" and "Neon Stairs" to enable each combo.
Let me know if you need any clarification.
Thanks!
Jonahtan
Hi, I am trying to make a lens in which i want to give multiple options for images, i have tried all the scripts i could find but none of them are working for me, please help me if you know the script for it. Thanks.
Hi mohandhir
What seems to be the problem?
Hi,
I checked out the script and it worked for me
https://drive.google.com/file/d/18FI9mu_s4taoaPjQDcyWHJkVTPOdGyZf/view?usp=sharing
Hi, n-mikael
Thankyou so much, this works for me.
Don't forget to save the script with Crtl + S
Hi there, pretty new to scripting and to Lens Studio, I tried to apply your code. The goal is to switch between many makeup models by touching the screen.
It works fine until it get at the end of the array. I thought it would restart from the index 0 when reaching the last item, but it is stuck on the last item.
Did I miss something ?
Thanks in advance for your help !
Seb
Hello, I tried to make a sound switch and it doesn't work for me((
Lena
this script isn't meant for sound its Tap to change on display. make a new thread also so more people can help you with this.
Lena
actually never mind I was reading the previous comments and saw he made another one but for audio here it is
https://support.lensstudio.snapchat.com/hc/en-us/community/posts/115020451643/comments/360000834386
Hello, ItzJustSamuel.
Sorry, I didn't specify what I can't do. Yes, I use it and it doesn't work for me. Can you tell me what I'm doing wrong?
Lena
The script is outdated, it looks like it doesn't work anymore.
Thank you, ItzJustSamuel. This sounds very sad.
I saw in previous messages that the script for replacing the image also did not work and Jonathan Solichin wrote how to update it.
Is there any way to update this script for audio?
Hey Everyone!
Glad to see all the creativity around what you can do with Lens Studio and tapping through objects!
In the latest version of Lens Studio, you can actually use Behavior to do this now! No more messing around with scripts :) unless you want to!
First you can create a Behavior that triggers custom triggers:
The important part here is the "Next in List" option, which allows the "trigger" to call different things every time it's triggered.
Next you can create another Behavior script where you define what each custom trigger will do, something like this:
For me, I arrange the scripts like this:
To add Behavior, go to the Objects panel > + > Behavior . You can learn more about it here: https://lensstudio.snapchat.com/guides/scripting/helper-scripts/behavior/
Let me know if you need clarification!
Thanks everyone, can't wait to see what you all come up with!
Jonathan
Hi - I'm SUPER new to this (like a client requested this yesterday and I'm figuring it out as I go). So I have zero clue what I'm doing. What I'm trying to do is be able to flip through face masks on tap. I figured out how to do a one-tap change, but I need to be able to cycle through 8 of them and I'm just not sure where to go next. I'm assuming it needs to be something different than what I'm doing. Any suggestions?
Hi Roberta,
You can use the script in the beginning of this post to provide a list of the face mask you want to change on tap.
Alternatively, as in your screenshot you can use Behavior. Take a look at the Behavior template in Lens Studio 3.2 to learn more: https://lensstudio.snapchat.com/templates/interactive/behavior/
Cheers,
Jonathan
Good to know, at this stage I am guess I am trying to future proof and push the box with what Lens Studio's JS can do :) and how to work in certain limitations (dynamic Text, no external API etc.