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!
Hello all !
I'm trying to switch between a few Audio Effects without any luck.
I tried to enable them via sceneObject but it doesn't seem to work.
I tried to modify with audioComponents and no luck either.
Is it possible ? Can you help me ?
Thanks a lot
Hey Jonathan! I have a similar thread that I started, but I am wondering if I would be able to use this same kind of technique to take the automated rotation I have created on a 3D object, and then pause and resume the motion on a Tap Event. Am I on the right track?
Hi Jonathan Solichin Sir I have the same doubt I want tap to change Image and I can't understand the code please can you help and make a same step by step post for it as I have many doubts as I am new to lens studio , I do no what to use a object or what and when I did it with the help of object following your process my image didn't change so can you make a step by step process for the image to change on tap . please help . and what is sprite what does it do ?
https://support.lensstudio.com/hc/en-us/community/posts/115020451643/comments/360000849203
Hi Jeoffrey!
Can you help me figure out what the issue is? What error or problem do you see when you follow this comment? https://support.lensstudio.com/hc/en-us/community/posts/115020451643/comments/360000834386
Hi Topher!
I'm glad Peter was able to help you out with this :) for anyone looking at this thread, you can find the answer in Topher's other thread: https://support.lensstudio.com/hc/en-us/community/posts/360042834292-3D-object-rotating-want-it-to-pause-on-tap-and-resume-on-next-tap-
Hi Ujjshah!
In the latest version of Lens Studio (2.0) we've upgraded the "sprite" component to a new component called "Image".
Thanks for pointing it out!
Please use the following script instead :) (which changes line 1 from Component.SpriteVisual -> Component.Image)
To create ScreenImage:
When using the script:
The script:
Thanks again everyone!
Jon
Hi Jonathan, I have a lens that I used the segmentation guide on and I need to change the segmentation texture on a tap how do I change the script to do this.
thanks
Hi Jonathan!
I'm fairly new to Lens Studio, and I'm trying to create a lens that toggles four different cat/dog head bindings on tap. Each one is a different script in the object panel, using the PetTrackingController (found in the Pet Lens Template).
I created the TouchCollision object, added the touch event, and added the invisible mesh as the "Mesh Visual 1". However, when I go to add the script component nothing is working (I assume it's because I'm trying to toggle between Script Objects...?).
Any help is appreciated! Screenshots attached.
Hi Janraps,
That's a good question. It's a bit tougher to do. If you checkout the Pet Controller script, you'll notice that the Pet effect is not the object the script itself, but rather the script is instantiating a prefab with the pet effect.
Thankfully, there's a function in the script to enable and disable all the instantiated object. What we need to do, is add the api to the script, so another script can enable and disable the pet effect.
in the configureTrackingVisual function of the petTrackingController, we can add the following API:
Then we can use the original script, but instead of calling .enabled, we can call the api we just defined:
Note the detail, where we check first on update whether the petTrackingController is ready, before we call our script to enable and disable the pet effect!
Let me know if you need any clarification.
Cheers!
Jonathan
Hi Jonathan!
I'm new to creator lens Studio, I've been trying to do this but I can't seem to make it work any help will be useful ill link a screenshot of the issue that I think I'm having, I copied the script from above, and yes I understand the script but I can't seem to make it work I think I did something wrong.http://snpy.in/vRUQCL
Did you save the script?
Click inside the script, and ctrl s
I thought it autosaves but thanks it works now
THAT WORKED thank you Jonathan!
Same as itzjustsamuel... I didn't realize you have to ctrl s each time you edit a script.
**Edited**
Hi Jonathan,
The steps you provided worked great. However, once the pet's face is first detected, the scene shows all 4 head bindings at once. The first few screen taps make them disappear one by one until the last one is left, then the tapping cycles through them one by one.
Any advice on how to have only the first headbinding show right away, then each tap cycles through as usual?
hey, Janraps you have to uncheck all of the items on the left side then you'll be able to use the script like this for example.
http://snpy.in/x9GQJW
Figured it out!
Jonathan Solichin in the TouchCollision script, I updated from this:
to this:
It now starts on the first pet headbinding script and cycles through perfectly on tap.
Thanks itzjustsamuel, that would indeed work as well; We'll try to make the "save" more obvious! There's a small asterisk right now that denotes that a script hasn't been saved yet.
Good catch Janraps! I will update the script above. The perils of copy and pasting code!
Thanks again everyone! Excited to see what you all come up with.
Hi Jonathan, one more thing I'm trying to do before the lens is complete.
I want a lens hint to appear only after the dog/cat's face is found, indicating that you can tap for more graphics (I'm calling them crowns).
I added the Lens Hints script and edited Hint Id to say what I want, but the dropdown menu doesn't include "Pet Face Found". "Face Found" isn't working on a pet face.
Is there a way to initiate the hint once pet face is found?
Hi Jonathan Solichin
I am having an obscure issue when using this top to change tutorial.
My lenses work in the editor, but not on my phone (I have an Iphone 11).
This is true for both the object swap and the image swap.
Do you know why this might be happening and how I could fix it?
Thanks so much! I look forward to hearing from you.
Hi Rhea,
Can you explain a bit more why it doesn't work. Does tap work? Or does the image swapping not work. Can you try using Behavior and see if tap works on that?
If you are still unable to resolve, can you share the project for us to take a look?
Thank you!
Jonathan
Jonathan Solichin
I was actually able to get it to work on my phone, but it only works when I set the event dropdown for the script to "initialized". I need this effect to work on snap camera (on a desktop), so this drop down value needs to be "tapped". However, when I set the dropdown to "tapped", the changing background does not loop back to the first background. (You can tap through the backgrounds, but the tap interface stops working when you get to the last background).
Any ideas why this may be happening? Is there another way to get the tap interface to work on snap camera?
Thanks so much!
فضلا ارغب معرفة خطوات صناعة عزل للخلفية ؟ بورتريت؟؟
Hi Rhea,
Hmm, that is interesting--I've just tried uploading it to snap camera and didn't have any issue.
Can you try this minimal project?
The other thing to try, if you want to try using the Tapped option in the Script component, is you can set the activateNextItem to be an api, and then call the API from another script which is set to activate on the tapped drop down.
Let me know if you need any clarification.
Cheers,
Jonathan
on initialized at the bottom of existing script
on another script set to on tapped
Danielle Rosenberg
Give Me the download link to your Project and ill do it for you but when I do it for you look around to see how things work and make sure you learn how to do it by yourself in the future.
Hey Jonathan Solichin, Could you help me with this Script it works well but I need it to work with scripts as well because when I tap the screen using this the script you made above it works only to go to the next script but it doesn't return to the script on value 0
Like this I duplicated the script so yes its not copying the same thing over and over its just not going back to Value 0 When I'm using Scripts instead of items
Hi ItzJustSamuel,
Can you check whether currentItemIndex loops back to 0?
This way we can figure out whether the issue is the looping back, or the enabling/disabling.
Cheers,
Jonathan
Hi ItzJustSamuel,
Can you check whether currentItemIndex loops back to 0?
This way we can figure out whether the issue is the looping back, or the enabling/disabling.
Cheers,
Jonathan
Enabling works getting it from 0 to 1, but getting it from 1 back to 0 doesn't so looping it back to 0 doesn't I'm using your Script from above
Thanks for reaching out as well
Hmm, it seems like it's going back to 0 for me. Can you share your project. Is the API disabling the object correctly?
I tried using this minimal case:
and it seems to call enable and disable correctly.
Thanks again,
Jonathan
Jonathan Solichin
://drive.google.com/file/d/1BHgJ8yiUE5TrGELc5_6QIWoBSIkJ1HLr/view?usp=sharing
I think the issue I'm having is that the script isn't detecting that the object is another script.
Can't figure out how to make this work
Say I wan't to combine this effect with the template "cutout", how would one do that?
I can make them work individually but putting them together causes problems