(upgrade : music sync time)
I’m going to explain here a simple way to play music, play music sequentially, and share your thoughts on how to sync music.
" Hi, nice to meet you
I don’t speak English very well, I’m sorry if you don’t understand
I’m not an expert, I just wrote this because I want to share my thoughts and help
Please tell me about the information that I did not think was wrong.
Any good ideas, advice please
I don’t know much, but I’ll try to write something to help
Please enjoy this "
- 0. what is this tutorial?
intro: hello~! I love listening to good music while watching the beautiful world on vrchat.
I wanted to play each music clip sequentially without combining multiple music into one clip.
udon was released while I was thinking, and I learned how to play music.
And further, I wanted to see the same people and enjoy the same moments in the same world. In addition to Object Sync and Video Player Sync, I wanted to enjoy the world while listening to the same parts of the background music and the same lyrics.
So I’m not good at various methods, but I did some research and made udon by asking friends around me.
This can be a bit odd. I hope I can give someone help or ideas, and I would like to discuss a better opinion.
Please tell me advice and ideas
- 1. how to play music in udon?
simply, To play music you need ‘audio source’ and ‘audio clip’.
1-1. First, create one object and add component ‘udon behavior’ and create a ‘new program’. and ‘open udon graph’
1.1.1 create any object
1.1.2 add component udon behavior
1.1.3 make new program and open udon graph
1-2. We need an event node to start the code. Bring up ‘start’ using ‘add node’ in the upper right
And we need to ‘set audio clip’ to play on the audio source. and we have to ‘play audio source’.
and Connect nodes in order
1.2.1 bring event node (event node tell when to run the algorithm udon code)
1.2.2 bring audio source set clip node (Tell the audio source which clip to use)
1.2.3 bring audio source play node (Command to play the audio source)
1.2.4 Connect nodes in order of execution (When executed, set the audio clip you want to play in the audio source, and play the audio source)
1-3. We have decided on an audio clip and have prepared the code to play the audio source. so we need make ‘audio source’ and ‘audio clip’.
And we need to decide which audio source to prepare and play (instance). And you have to tell them which audio clip to use. (value)
And in order to connect the ‘audio clip’ and ‘audio source’ in the udon code, you need to put it in a variable, and get use ‘get variable’
1.3.1 Prepare an audio clip(audio file) to play
1.3.2 Then create an audio source.
(126.96.36.199,2) Uncheck the ‘play on awake’ checkbox
1.3.3 bring variable audio source node
1.3.4 bring variable audio clip node
1.3.5 Name the variable you want. And check the public checkbox
1.3.6 After checking the public checkbox, you can check the public variables in the udon behavior of the inspector window.
And you can drag and drop audio sources and music into the variables
1.3.7 bring get variable node (After setting the variable, you need to get the value contained in the variable)
1.3.8 Use ‘get variable’ to get the audio source and audio clip contained in the variable and connect it to the udon code
‘instance’: get variable containing the audio source (to tell which audio source to set the clip to and which audio source to play)
‘value’: get variable containing the audio clip (in order to tell which music to set to the audio source)
CODE: play music
play music show udon code
Note (1-4.) If you added audio source using ‘Add Component’ in object, you have to use ‘game object get component’
(1.4.1) If you added audio source component inside a game object, you should use ‘Get Game Object Component’
instance : To get the component added to this game object, we use ‘this’ node to let us know that we are this object.
type : Use the ‘Audio Source Type’ node to bring up the audio source component.
CODE: play music (use get component)
play music (use get component) show udon code
- 2. music play list
So far, we have learned how to play music from basic udon usage
In Chapter 2, we will talk about how to play multiple songs in order
We will check whether the music is playing or not to play the music in order, and then play the music if it is not playing.
And by numbering by audio clip, each time you play it will set the next number of audio clips in the audio source.
2.1.1 This is a complete shot of the music playlist code
2.1.2 all variable
bool : Variable with true or false value (defaults to false)
audio clip : It is a variable that can hold an audio clip like the one used above. The difference is that
array () can contain multiple clips, not just one.
audio source : As used above, it is a variable that can contain an audio source. (There was also a getcomponent method above, but I will use the public variable method here.)
int : It is a variable that can hold an integer value.(like …-2,-1,0,1,2,3…)
Here, two int variables ‘now_music_number’ and ‘clipsize’ are used.
‘now_music_number’ is a value that indicates the array number of the clip to be played, and ‘clipsize’ will contain a limit value so as not to exceed the maximum value that ‘now_music_number’ can represent.
2.1.3 We’re going to make an algorithm that checks whether the music is currently playing or not, and if it isn’t, plays the music.
update event : This event is called every frame
branch : is an if statement. If you connect the bool value to the circle of the left down, it makes the behavior different if true and false.
audio source get is playing : Tells whether the audio source connected to the instance is playing or not(true or false)
audio clip get : Select which of the multiple songs in the audio clip array to import. (The audio clip array starts from 0. So, if 3 songs are entered through the array variable, the song numbers will be 0,1,2 in order.)
Use ‘audio source get is playing’ and ‘branch’ to determine if the audiosource is playing.
If is not playing, set the clip of the number of the audio clip array to play in the audio source.
Play an audio source.
set variable : Set the value of the variable (enter the value to set in ‘value’)
int addition : (+) Adds integers together.
int equality : (==) Determines whether integer values are equal or not equal to each other. (true or false)
const int : has one integer value (constant)
You need to play the first music, 0, and when the 0 music is over, you need to play the 2nd music, 1.
The ‘now_music_number’ variable, which tells you the number of the song to play, will be added 1 to the variable after the music is played.
If you do this, if you add 1 after playing the music in ‘now_music_number’, the played music is 0, ‘now_music_number’ is 1.And when the 0th song is over and the code works again, it plays 1 in ‘now_music_number’ and adds 1 again to become 2.
In this way, 0,1,2 clips are set in order.
However, if you continue in this way, ‘now_music_number’ will have a numeric value that is not in the audio clip array(because keep over added).
Therefore, if we exceed the value of the audio clip array that we set, we need to set the value of ‘now_music_number’ back to 0, which is the initial state.
on player joined event: An event that starts when the player joins.
boolean unary negation (op unary negation) : Invert the value of bool. Change from true to false or false to true.
Change bool’s false to true when the player joins.
As a result, this bool value causes the update to start after the player joins. And even if the second player joins other than the first player, only the bool of the recently joined person becomes true, and the bool of the existing player remains true.
This algorithm is described in “Why Did You Do It? (about problem, bug?)” Below.
2.1.6 how to use?
audioclip size: Enter the number of audio clips to use
Then drag the audio clip below to the variable.
audiosource: Drag the audio source into the variable.
clipsize: Please input the ‘audioclip size’ value once again. (Because the audio clip array starts from 0, if you enter 4, it becomes 0,1,2,3. Therefore, the limit value returned to the initial value is It should be 4 after adding 3 to 1.
Then ‘now_music_number’ plays 3, and when it becomes 4, it is the same as 4 of ‘clipsize’, so it is made 0 again and repeated in order.)
music play list show udon code
- 3. music sync play
Now let’s finally learn how to sync the music that is playing.
This code ensures that even if the player joins the world in the middle, the player can listen to the music at the same time as the player was listening to.
If you are in the same world, you can share the same music.
I’ve had a lot of trouble creating this, maybe it not be accurate, but I’ll share it.
The basic principle is as follows.
Record the song number and playing time of the music being played based on the oldest person in the world (we call this person the ‘master’ (when the master leaves the world, the next oldest person becomes the ‘master’)).
At this time, the recording is made in the synced variable (none).
And when someone other than the master enters the world, the music is played by reading the song number and playing time recorded by the master.
Therefore, in order to match the sync of music, people other than the standard play music based on the standard one (in this case, ‘master’).
The explain mainly focuses on the parts that are not explained in the above two examples (because it is based on the music playlist).
3.1.1 This is a complete shot of the music sync play code
3.1.2 all variable
float : floating point numbers variable (like : 20.0, -3.12, 0.12513)
synced (none) : Synchronize variable values (Here, we check the sync of 3 variables.
The float variable stores the master’s playing time. And the two int variables suit the value associated with the number of the audio clip.)
3.1.3 Identifies whether the player entering the world is master or not.
By default, the sync variable can only change master, but if a player other than master affects the value, synchronization may not work properly. Therefore, we need to distinguish between the master and the not master.
3.1.4 The algorithm that runs when the master.
audio source get time : Get the play time of the audio source (float).
audio source set time : Set the playback time of the audio source.
In the case of a master, in synced variable (time_float), the time of the audio source being played by the master is input to the variable every frame.
And when the audio source is not playing (when the music is finished playing)
Enter 0 in sync variable (time_float) and sync variable (time_float) to
audio source set time before playing music each time.
Then, enter the value of sync variable (now_music_number) in sync variable (sync_music_number).
If you do this, the sync variable (now_music_number) prepares the next audio clip number, and the sync variable (sync_music_number) has the audio clip number that the master is listening to.
3.1.5 Algorithms executed when not master.
Get and set the clip number and time value of the audio source that the master is listening to.
When the audio source is not playing and the sync variable (time_float) is not 0, the clip number is set with sync variable (sync_music_number), and the playback time is set with the sync variable (time_float).
CODE: music sync
music sync show udon code
Why Did You Do It? (about problem, bug?)
Here, I will share some of the problems that I encountered while writing code.
This is about my thoughts, so it may not be accurate.
When I entered the value of set variable as get variable, it did not work.
So I solved it by entering by adding 0 to get variable.
As an update event, when the audio source is not playing, it is played and the clip number is added by one. However, for a short period of time (approximately 60 frames) when joining the world and fading in from the black screen to the world screen, the audio clip number increased and the music was not played.
So I solved it using bool and on player joined so that the update command starts after the player joins.
(Maybe anothe way, is we can solve this by making the clip number count from the time the audio source is played.)
We confirmed that the sync was not working properly when the player, not the master, joined the world, fetched the synced variable, set the time and clip number, and played it. Sometimes it worked, but sometimes it didn’t.
Even if it works well sometimes, i checked if there is a minute time difference (about 0.0 … ~ 0.4 …) when the receives the time after playing music.
So, I made is not work when the synced variable (time_float) value is 0
I thought that if the value of synced variable (time_float) was not 0, it would be after synchronization. (because Initial value is 0) and fortunately this worked well.
While testing as the master and non-master players left the room and came back in, the audio clip number increased well, but found that the audio time was fixed at 200 seconds.
Before trying to play the music, I think two methods of initializing the variable each time or using two audio sources
fortunately it worked just fine used first methoed
It was solved by always setting the synced variable (time_float) to 0 and setting the playback time to 0 again before the master played the music.
During the synchronization test, I started the clip number with -1 and set the clip number to play after the code added 1.
But sometimes -1 was entered as is, the code didn’t work.
So I fixed it by modifying the code to make it start at 0 and adjust the order of adding 1.
Thanks for reading
This method maybe inefficient or may not work smoothly
Please share on a better way or idea
I hope you can enjoy the background music synchronized in many worlds
please enjoy this