Hello everyone ! In this post I will breakdown the Sound Provider component and show you how you can customize the audio experience in your game.
- Have a little coding experience. (Would be great if it is lua)
- Have already gone through this page and followed its instructions.
- Knowledge on how interactable component, Events, EventHelper, CustomEvents work for the complex section.
Add the Audio component to any object.
This is how the audio component looks with an audio added to it.
Currently only the starting of the audio can be customized with the trigger portion of the component.
Here the audio chosen is
Casual Game Music 20. It plays on start, that is, the audio starts playing as soon as you load the space.
We can do the same thing as the above component using a simple script. For scripting purposes we will have to remove the Audio component and instead add the Sound Provider component under the node category of components. Its the same symbol as the Audio component but in yellow.
Here’s how the sound provider component looks after adding an audio.
After this you will need to add an script. For this click on the arrow beside the (+component) button and choose
Give your script an appropriate name.
Note : your script name can contain only letters and numbers, so no symbols or spaces
I will name my script
Then click on your file name beside the file field to open it up in your preferred Editor.
This is simply for some technical reference, you totally do not need to understand the following codeblock.
---@class YaSoundProviderComponent : AbstractHybridYaComponent YaSoundProviderComponent = Class() --- Return current clip's length. ---@return number function YaSoundProviderComponent:GetClipLength() end --- Set Track length. ---@param length number function YaSoundProviderComponent:SetClipLength(length) end --- Set the "volume" as the sound volume,which ranges in [0-1f]. ---@param volume number @Sound Volume. function YaSoundProviderComponent:SetVolume(volume) end --- Get the "volume" ,which ranges in [0-1f]. ---@return number function YaSoundProviderComponent:GetVolume() end --- ToDo Api,which allow "Sound Provider" can play different sound clip. ---@param musicID string function YaSoundProviderComponent:ChangeSong(musicID) end --- Return "Sound Provider" whether is playing clip or not. ---@return boolean function YaSoundProviderComponent:IsPlaying() end ---@return number function YaSoundProviderComponent:GetSoundId() end --- Make "Sound Provider" play from last track point. function YaSoundProviderComponent:Play() end --- Make "Sound Provider" play from head of the track. function YaSoundProviderComponent:Replay() end --- Make "Sound Provider" pause from playing. function YaSoundProviderComponent:Pause() end --- Set Sound 3D ---@param isThreeDimension boolean function YaSoundProviderComponent:SetThreeDimensionalSound(isThreeDimension) end --- Set Max Min Distance ---@param minValue number ---@param maxValue number function YaSoundProviderComponent:SetMinMaxDistance(minValue,maxValue) end --- Set Loop ---@param Looping boolean function YaSoundProviderComponent:SetSoundLoop(Looping) end --- Get Loop ---@return boolean function YaSoundProviderComponent:GetSoundLoop() end
We need to work with the above class. That is we will edit attributes of the component using functions defined by it. So we will need to have something to refer to it. So we will store the component attached to our object into a variable.
local audio = script:GetYaComponent("YaSoundProviderComponent");
- We store the object in the variable
- We get the component from the object to which this script is attached to. Hence,
- We take the required component by mentioning it within quotes.
Now we have to play the audio as it won’t be played automatically. For that we use the Play() method.
This will play the audio as soon as the game starts because that is when the script is executed.
So, the total script looks like this right now :
local audio = script:GetYaComponent("YaSoundProviderComponent"); audio:Play();
Now if you hit play and enter the game you can hear your audio playing.
Yes it is 2D audio by default. This means that the audio is not spatial and you don’t hear it coming from a particular direction, instead it plays like a background audio.
For this we will need to use the SetThreeDImensionalSound() method.
Add the following line to your script befor
This will change the audio to spatial which you can confirm by going into the play mode. You can change it back to 2D by setting the above value of the function to false.
We can change its volume using the
To change volume you will need to add the following line
value is the volume amount. Replace it with the amount you want.
KEEP IN MIND : The value of volume here is different than in Audio component. In Audio component you choose a value from 0-100. Here you have to use a value between 0-1. That is if you want 70% volume then keep the value as 0.7.
The audio stops after playing once. You might want it to repeat multiple times.
Add the following line before
In this section we will get into changing properties of the audio based on various conditions and from a different script.
Simply changing the audio on a trigger. Instead we will use
Interactable component is the same as trigger but the differences are :
- It triggers only for players and not for any object
- Its shapes are cylinder(default), sphere, capsule. No box.
We will add a cylinder to our scene and turn of its mesh collider.
Do not add a trigger, its not needed.
Then add the Interactable component to it.
You can change the values here if you want to but its fine to keep them in default. The values for Radius and Height say 0 but they are actually 1. So, it perfectly aligns with the cylinder mesh and helps with visual reference.
No add a script to the object and name it
AudioTrigger. We will trigger various events with this script.
Each subtopic in this complex section will assume this script is empty at the start of that topic.
Write the following in the script.
local intcmp = script:GetYaComponent("YaInteractableComponent"); local function ChangeAudio() CustomEvents:Emit("ChangeAudio"); end EventHelper.AddListener(intcmp, "PlayerContactEvent", ChangeAudio);
- intcmp is the variable for the interactable component.
- ChangeAudio is a function that helps us changing the audio.
- Last line is where we listen for events from
intcmp, we listen for the event
PlayerContactEventwhich is emmited when the player enters the interactable component range(here a cylinder with height and radius of 1), then we call the function
ChangeAudioif the event is heard.
Now the function
- It will emit the event “ChangeAudio”. As it is a custom event, it does not need to refer to any object.
Fun fact : this line can also be written as
Before we edit the script, we need to make note of the audio we want to change to. Remember the name of the audio file as it appears in Yahaha along with the case.
We need to listen for the event from AudioTrigger script and when it is heard, we will change the audio using the
Add the following block to your AudioManager script :
local function ChangeAudio() audio:Pause(); audio:ChangeSong("Audio name"); audio:Play(); end CustomEvents:AddListener("ChangeAudio", ChangeAudio);
Replace “Audio name” with the name of the audio you took note of earlier. Make sure to type the name within quotes inside the parenthesis.
- We pause the currently playing audio
- Then change the audio
- Then play the changed audio
- Event listener calls the function when the it hears the “ChangeAudio” event.
You can probably notice now that the code is pretty self-explanatory.
- Create an interactable component.
- Create a function to emit certain events for your purpose.
- Call the function when the event PlayerContactEvent is emmited by the interactable component.
- Listen for the Custom event you emmited in some other script.
- Call the function that is supposed to do the stuff related to that event.
AudioTrigger Script :
local intcmp = script:GetYaComponent("YaInteractableComponent"); local function PlayAudio() CustomEvents:Emit("PlayAudio"); end EventHelper.AddListener(intcmp, "PlayerContactEvent", PlayAudio);
AudioManager script :
local audio = script:GetYaComponent("YaSoundProviderComponent"); local function PlayAudio() audio:Play(); end CustomEvents:AddListener("PlayAudio", PlayAudio);
I hope this is self-explanatory
Here we will have to work with a class called
YaTime. It has no official documentation. Ekki found out how to make it work with the help of Kim.
---@class YaTimeComponent : AbstractSingletonYaComponent__YaTimeComponent__ YaTimeComponent = Class() ---@return number function YaTimeComponent:CurrentTimeSinceStart() end ---@param seconds number ---@return TimeEventContainer function YaTimeComponent:WaitFor(seconds) end ---@class TimeEventContainer : Object TimeEventContainer = Class() ---@type fun() TimeEventContainer.TimeEvent = value()
The concept for this would be we play the audio and then wait for a set amount of time before pausing the audio. This won’t require the interactable component scripting.
We need to start the AudioManager script as usual.
local audio = script:GetYaComponent("YaSoundProviderComponent"); audio:Play();
Now after we play we need to use the
WaitFor method of
YaTime class. As YaTime is not a component in a studio, we cannot get it using
GetYaComponent. Instead we use
YaTime, which is an accessor for the YaTime class.
WaitFor function emits an even “TimeEvent” when the time of waiting is done. We listen for that and then call a function to pause the audio.
We can do the delay by writing
YaTime:WaitFor(Time), where you replace ‘Time’ within parenthesis with the amount of time to wait in seconds.
Now to listen to this event we need to store it in a variable.
So add the following line in your code.
eventcontainer = YaTime:WaitFor(5);
Now we need to define the function for pausing the audio :
local function PauseAudio() audio:Pause(); end
We call this function when
eventcontainer emits the
Note : this is not a Custom event, so we need to use EventHelper.
Add the following line to your script now
EventHelper.AddListener(eventcontainer, "TimeEvent", PauseAudio);
That’s it for now as I cannot think of any other situation. So, if you have ideas for any other situation do tell me and I will add it to this post.