How to Create a Music Toggle Button - Udon/ VRChat SDK3.0

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
i'd like to create a music player with multiple buttons to turn on different pieces of music here's how we're doing that first i'm going to create a button to toggle on and off one bit of music and then i'm going to expand the script from there to start off with i'm going to come into my hierarchy and i'm going to right click go create cube then i'm going to come back to the inspector and scale it down to 0.1 0.1 0.1 then i'm going to fly around in my scene and go ctrl shift f to place it where i am and then i'm just going to reset its rotation then as this is a button and i don't want people colliding with it i'm going to come down to the box collider and select is trigger to equal true next i'm going to come down and go add component audio source and i'm going to pick the vr chat one now it's time to change some of these settings i'm going to come down to my vr chat audio source and i'm going to hit this little drop down menu and disable enable spatialization this will make the audio play in our ears instead of sounding like an object in the world then on the unity audio source i'm going to come up and enable looping and disable play on awake and finally i'm going to grab my audio clip and plug that into the audio clip slot now as music can be kind of scary on youtube today's music of choice is just a recording of a really annoying tiny computer fan now that we have the music sorted we want to give this button some logic we want to come down and go add component udon behavior now i want to create the script to go inside this component so when i come down to the project window go create vr chat udon udon graph program asset and i'm going to name it music toggle and then you want to come up and open up the udon graph now that when the udon graph when i come over to the variables tab we want to hit this little plus button and create an audio source we're going to call this target audio source and i'm going to hit this little drop down menu and make it public so we're able to select it inside the inspector now when i come into the graph we want to right click and go create node the shortcut for this spacebar and then we want to type in audio source play now we want to say what audio source we want to play so we want to grab our target audio source and drag that into the graph and we want to connect that into the instance slot so now whenever this node is called it will tell this audio source to start playing and now we want to create another node to make it stop we want to go create node audio source stop and set it up the same way and now we have a node to make it play and a node to make it stop we want to create a branch node and we want to plug the true into the play and the false into the stop so now whether or not this ball is true or false will determine whether or not we play or pause the audio source so now we need to tell it whether or not we want to play or not to do so we're going to grab our target audio source we then want to go audio source get is playing and what this will do will give us a true and false statement as to whether or not the audio source is currently playing then as we want the inverse of that we want to grab our ball and we want to put that into a bull unlunar negation now i don't know the history as to why we call it this but this node will flip the value to be the inverse of what it is making the false true and the true false we just want to grab this ball and put that into the branch node so now whenever this branch node is called it will look at the target audio source and see if it is plane and then it will do the inverse of that so if it's playing it will make it stop and if it's not playing it will make it play awesome so now we just need to say when we want this branch node to be called we can create an event interact node and plug that into the branch node and so now whenever we click the button it will play all this logic awesome so now when i come back into our scene and we want to click on our button we then want to come down to our urdon behavior component and give it our new script then i'm going to change this interact text to say toggle music i'm then going to come up and grab my audio source and then drag and drop that into the target audio source slot so now it's time to test this i'm going to be play testing this inside mu which allows me to do it inside the inspector and now that we're in the world we can see that when i click the button it plays the music and when i click it a second time it turns it off brilliant so what if we wanted to make this networked well we can come back into our udon graph and we want to create a new variable so i'm going to hit this little plus on the variables tab and i'm going to create a ball i'm going to call this ball is plain and i'm going to hit this little drop down menu and make it a public synced variable now we need to change up the script slightly so that this branch node works on whether or not this bull is true or false i'm going to grab my ball and plug that into the branch node and then i want to create an event that's going to change the state of the ball i'm going to call this change state i'm going to grab my is playing bull and drag it while holding ctrl and this will create a node that will set the ball and now i want to put the output of change node into the set node ball and then i want to grab the earning irrigation and put that into the value slot now i want to grab my ball and drag into the scene while holding alt to get an event that gets played whenever this ball changes then we want to drag it into the branch node and so whenever this build changes it will run this logic coming back to our send change node we want to make sure that send change is selected otherwise it won't play for the owner of the object so now all that's left is to call this event so i'm going to go ood on behavior send custom networked event i then want to put out interact into it i want to make sure it's target to set to owner as only the owner is able to change the synced variable and then for the event name i just want to select the one that we just made so now whenever we click this button it will send a custom networked event to the owner of the object the owner will now run the custom event it will look to see the audio source and see that it is plain and do the opposite and set that as the ball value then when people see the ball has changed they will update the play state of the audio source and now it's time to test this i'm going to hit compile and then go to my vr chat source and run two instances so we can test the networking and now that we're in the world we can see when someone clicks the button it turns it on for everyone else and if was to hit it again it turns it off awesome now what if i want to make a different button that changes the music being played well before we do that as we're dealing with multiple buttons we want to take the audio source off the current button and put that on its own game object this is mainly for cleanliness as well as readability as well as it also means that you can delete all your buttons and not destroy your music player so we're going to go to the hierarchy and create an empty game object we're going to call this music player we're then going to go to our old audio source hit this three little dots and go copy component we then go back over to our music player we hit the three little dots on the transform and go paste component as new then we want to do the same thing for the vr chat audio source and now we should have an identical copy on our new music player then all that's left is go to our old button and delete the vr chat audio source and then get rid of the unity audio source and you will have to do it in that order now we're going to go to our udon script and just give it the new audio source that we just created on the other game object so now it's time to create a button that will change our audio clip i'm just going to go ctrl d to duplicate it to create my new button and now it's time to create the new script that will go inside this udon behavior component so in the project window we're going to right click go create vr chat udon udon graph program asset and i'm going to call this music changer and then i'm going to open up the udon graph now that we've got the udon graph open we need to create some variables i'm going to hit the little plus button and create an audio source call it target audio source and then hit little drop down menu and make it a public variable i then want to hit the plus again and create an audio clip and this one i'm going to call music clip and i'm going to make this one public as well so now when i come into my graph i want to go create node audio source set clip this node will set what clip is being played on the audio source so we just want to grab our target audio source and put that into the instance and then put our music clip into the value slot so now whenever this node is called it will tell this audio source to play this audio clip we just want to grab an event interact node and plug that into the set clip node awesome so now i want to come back into our scene and click on our new button we want to give it our new urdon behavior script and then we're going to change this interact text to say change music and now we need to tell it the audio source and the music clip we want it to play so i'm just going to grab my music player and put that into the target audio source and then i'm going to grab my new clip and put that into the music clip slot awesome so now it's time to play and test this so now that we're in the world we can click on our original button and we can see that toggles on and off as we expect and now when we click on our new button and go back to the old button we can hear that the music has changed now there is a slight problem with the script if we come and play test again and we turn on the audio and then we go to change the audio we can see that the audio stops playing and we have to come back to the original button to get it to play again now in one of my test runs this was even worse and it wouldn't start playing at all it seems like it just completely crashed we need to account for this in our code however it's pretty simple coming back into our code the fix for this is to tell audio source to stop playing change the clip and then start playing again we can go audio source stop and this will stop the clip from playing and then we want to plug that into the set clip and then we want to do another one of audio source play now we need to say what audio source applies so i'm just going to give it our audio source so now whenever we click this button it will stop the audio source it will change the clip and then it will make it play again now there's a side effect of this because now whenever we click the button it will always turn on the audio source and this might not be ideal for what you're after in order to account for that we need to grab our target audio source and we want to put that into an audio source is playing node and this will give us a ball of whether or not it is plane or not we then want to put that into a branch node and only if it is plane do we want to do our logic however if we're not playing all we need to do is set the clip so i want to grab that part of the code and duplicate it down and put the false into that bit of logic so now whenever we click a button if it's not playing it will just set the clip but if it is playing it will stop the clip change the clip and then get it to play again awesome so now it's time to test this now that we're in the world if we click our button to start playing the music and we click on new bone we'll see that it changes the music clip and keeps playing so now that we have both these scripts what if we wanted to combine the two so that the button that changes the music also turns it on and off to do that i'm going to copy this bit of my script and i'm going to go back to my music toggle script and paste it in now we have two target audio sources so i'm just going to delete the one that we imported and replace it with the one from this script now looking over our toggle script the way that we did the nipkin here unfortunately won't work for the new script so i'm just going to revert it to the way it was before and now we need to do a little bit of logic to see what bit of the script we're calling now the only time we want to change the clip is if the clip on the audio source is not the clip we want to play to check this we're going to grab our audio source then we're going to go audio source get clip to get the audio clip that has currently being played on the audio source then we want to grab our music clip and then we want to check if it is the same as the one on the audio source to do so we can go audio clip equals and this equals node will return a ball that will equal true if they are the same and false if they are not so we can put that into a branch node and then we can put the false of the branch node into the logic that changes the audio clip so now if we put our interact node into the branch node if the audio clip is different it will change the audio clip being played however if they are the same it will run off this true statement and we actually want to plug that into the branch node that's up here so to explain the script a bit more clearly i should run through a couple of scenarios the first scenario is that we're trying to play a new piece of music so when we hit this interact button it will go to the branch node it will look at the audio source see its clip is different to the clip that we want to play and so it will equal false then it will come down here and stop the audio source change its clip and then make it play so now what if we hit it a second time it's been playing the clip that we wanted to play but now we want it to stop when we go to the interact button it will go to the branch node it will look at the audio sources clip and see it is the same as the music clip and so it will equal true it will then come up to this next branch node and look at the target audio source and see that it is playing and do the inverse of that and it will come down and tell it to stop so what happens if we hit this a third time when the interact event is called it will go to the branch node it will see that the target audio source's clip is the same as our music clip so equal true and come up to this next branch node it will then look at the audio source see that it's not playing and flip that to equal true and then that will tell it to play the audio source so now we've successfully combined both these scripts we want to hit compile and then go back into our scene view i'm going to click on our first button and give it the music clip we want it to change to and then i'm just going to change this interact text to say music 1 and then i want to select the second button and change its urdum behavior script to music toggle i'm then going to change this interact text to be music 2 and then i'm going to make this target audio source the music player and now we can test this so now that we're in the world we can toggle on music 1 and then we hit music two it changes to music too and if we hit music two a second time we can see it turns off so now we can turn it on and off as well as change whatever clip we want it to be so now the cool thing about this is that i can click on my button go ctrl d to duplicate it to create a third button i can give it my new audio clip and i'm just going to change the interact text to be music free and now when i play and test we have now successfully added a new button with a new audio track okay so what if we wanted to make this networked well unfortunately because of the way that we've done it it's going to take a few more nodes in the previous examples the first thing we're going to do is we're going to grab everything and we're going to copy this over to the side not including the interact node because you can't have two of them now i want to separate it out for all the possibilities for play and all the possibilities for stop and we're going to make a custom event play and a custom event stop accordingly so currently we have three outcomes the false from the first branch and then the true and false from the second branch now it's only the false from the second branch that leaves the auditor stopping so i'm just going to select it and copy it out and i'm going to create a custom event and i'm going to call it stop music so now whenever this event is called no matter what happens it's going to stop the music and now i want to create a second custom event and i'm going to call this play music and plug it into where the interact node was before so now whenever this event is called it will check whether or not the audio source clip is the same and if it is not it will change the clip however if they are the same it will come up to the second branch and will check whether or not the audio source is currently playing if the audio source isn't currently playing it will tell it to play but if it is currently playing it won't tell it to stop that is important because we want to play this custom event whenever someone needs to be updated to the current state of the music and whenever this play note is called it will restart the audio clip so let's say you had a late comer join into your match when you sync them up you don't want them to reset the music for everyone in the scene instead it's usually totally fine to have them playing at a different part of the music so now with these two events if we tell it to play it will always play and if we tell it to stop it will always stop so now we need to call these events coming back to the original part of the script we're going to create an udon behavior send custom networked event now we want to make sure the target is set to all and we want to change this event name to play music i'm just going to duplicate that and bring it to the one below and this event is going to be stop music and finally we need to come to the bottom and this one's going to be play music so now whenever i click the button if my audio source is different it will come down here and hit play and tell everyone to play this event then whenever this event plays if their audio clip is different to mine it will come over here and change the audio clip and play it if the audio clip is the same for them but they're not currently playing it will tell them to play and if they are already playing this clip it won't do anything at all now we've been a bit naughty with our coding and we would get away with it but currently when you tell the audio source to play it is then sending the custom networked event which includes yourself and then we're doing the logic and the script's going yeah i'm already playing and just isn't doing anything but because we're playing this event anyways there's no need to have this play audio so we can grab from the branch node and directly plug that into the send custom networked events and with that we've made our script just a little bit neater okay so currently this code will work for those in the world but it won't work for newcomers so we need to account for that to start we're once again going to copy this and duplicate it downwards this time and we need to do a little bit of logic so when a new player joins we want the owner of the audio source to update everyone on the current state of the audio source i'm going to go create node networking is owner and this will give us a ball value on the owner of the object now the object in question is the audio source not the current button we're playing so we want to grab our target audio source then we want to go audio source get game object and then we want to plug that into the networking is owner i'm going to put that ball into a branch node and we need to say when we want this branch node to be called so i just want to go in event on player join and plug that into it so now when someone joins everyone will check whether or not they are the owner of the object and if they are we want to do a couple of checks so i'm going to grab this truth and i'm going to put this into the branch node first we want to check if the audio source's clip is the same as the music clip for this button if they are the same this means this was the last button to be pressed if they are not the same this means this wasn't the last button to be pressed and therefore we don't want it to do anything so i'm going to delete the send custom networked event next we want to check whether or not the audio source is playing and if it is playing we want to make sure that everyone knows that it's playing now the code that we borrowed this from was to toggle it instead we want to grab this as plane and directly plug that into the branch this is because we want to update everyone to the current state and not a new state awesome so now we have a way of updating the music player for any newcomers that join the scene however there is a slight improvement we can make here if i was to drag away the on player join and replace it with a custom event i'm going to call mine resync music we now have an event that can be called as say like a debug button for anyone that might get desynced while playing let's say you're an oculus quest user and you take off your headset you won't receive networked events while you're afk so we can account for that for having say a reset button feel free to look at my video and call in another script to learn about how to do that now the real reason i made this event was because i wanted to create a delay so that when a player joins it waits a little bit before sending all the networked events we simply want to put our own player joint into an udon behavior send custom event delay seconds i'm going to change the event name to be resync music the event that we just made and i'm going to change the delay to let's say one second okay okay so that was a big bit of scripting and you can really start to see udon graph really struggle with scripts of this size hopefully they're able to optimize this more in the future a feature i'd love to have is for not to compile every single time you create a node and so if i could do a manual compile that would be amazing but currently if you want to make scripts that are much larger than this you're going to have to go to another compiler like udon sharp which is the more traditional coding method and is basically the only way to do things like vehicles but anyways it's now time to test this i'm going to hit compile and then i'm just going to do my sdk and run two instances so we can test out the networking and now they're in the world we can see that when one person plays it plays for the other person as well and this is an amazing concoction of noise anyways hopefully that was helpful for you feel free to leave a like on the video if you liked it leave a comment down below if you've got any questions and feel free to check out some of my other tutorials that i have on the channel but until next time bye
Info
Channel: PlayerBush001
Views: 15,003
Rating: undefined out of 5
Keywords: VRChat, SDK3, Udon, Worlds
Id: 4ENVC7cCiUU
Channel Id: undefined
Length: 18min 19sec (1099 seconds)
Published: Fri Jan 28 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.