How to play Polyphonic/Overlapping Sound Effects! - Godot 4 - Intermediate Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's up guys so in this video I'm going to be showing you how to play polyphonic audio in gdau so I'll be showing you a system which I typically use to play audio and this is pretty efficient and also allows for easily changing audio resources as you won't have to define the path inside your script anywhere and you won't need to make any constants or preloads for any of your audio files since they will be loaded into resources now an explanation of what this system will do is we'll essentially add the functionality to play audio which overlaps and you'll be able to Define different tags so instead of calling like play the specific sound effect file you'll be able to just call play like a jump effect and then the jump effect will Point towards a resource key and it will just look up the audio stream for that key some benefits to this system are one if you have things like enemies you'll be be able to Define an audio library and have the same keys so basic things like a hit effect or maybe like apply damage or something like that but you'll be able to Define it inside an audio library but for the actual stream that is playing you'll be able to Define that specifically inside of each instance separately outside of the base scene another benefit to using this system is you'll be able to play overlapping audio now you may have noticed that if you use just a generic audio stream player 2D you can only assign one audio stream as the stream property and for this instance I've loaded in my checkpoint sound effect and then if we play the game I'm just assigning the play to my space key but if you listen it'll play the sound effect but if we play it really quickly consecutively it will cut itself off so when the new sound effect starts the old one will stop now you can override this with the max polyon value inside of the audio stream player 2D so if we set this to something like 10 and we tried this again the audio would now overlap now the only problem with this is if you want different audio streams you'd have to replace the value inside of the stream property and this would obviously remove your checkpoint sound effect and make it so that you have to play a different one now this system is obviously going to fix that but to set it up we're going to make a few basic classes so I'm going to go into my scripts folder in the bottom and I'm going to rightclick and create a new folder called my classes and then inside of that folder I'm going to rightclick and create a new script and this script is going to be called sound effect. GD and we're going to extend resource so inside of the inherit property we'll say resource if you forget to do this you can always open up the script and change the value right here but just make sure we are extending resource and then we can Define the class name with class name and the value is going to be sound effect and make sure to do Capital case and inside of here we're just going to need two basic things so we'll need a key for the sound effect at export bar and this will be called the tag and we'll set it to a string and again this is what we're going to be using to identify what audio stream we're playing and then for the actual audio stream we simply type at export bar and this will be the stream and the type will be an audio stream and this is all we'll need for the sound effect class so we can go ahead and save this and then we're going to right click in the my classes folder once again create a new script same thing where we're inheriting from resource and the name of this script is going to be audio library and an audio library once we create it is essentially going to be a collection of sound effects and this is because statically typed dictionaries aren't yet supported in Gau so if we created a new audio library and then we exported a dictionary of sound effects we wouldn't be able to manually Define like we want the keys to be strings and the values to be an audio stream and this should be supported in future versions of gdau but I'm on 4.2.1 currently and we we cannot do this so the easy workaround which saves the user a lot more time is just to export a custom resource like this and then this is essentially the key to the dictionary and this is the value but it's easier to kind of create entries to that dictionary on the fly so instead of a dictionary since we're using this as the entry in our audio library we're just going to export a new variable and this is going to be sound effects and the type is going to be array and this is where we can statically type and make sure it's an array of sound effects and then I also forgot to define the class name at the top of this script so just make sure you type class uncore name and we're going to say audio library now when we save this we can go into our file explorer I've created a resources folder but we're going to rightclick inside of that create a new resource and search for audio library if we create a new audio library give it an ex sample name and then when we open this inside of our inspector panel on the right hand side we're going to have a list of sound effects and when we click into this we can add a new element and in here we just Define a new sound effect and inside of here we can give it a tag so in this case we could say like this is the jump sound effect and then the stream we could quickload in the player jump and now this is kind of the same thing like I was talking about where you have a dictionary except it's all statically typed so we don't need to manually assign the stream value as the key so I'm going to delete this custom resource that I've made and we're going to finish out these methods inside of our audio library class so inside of this script we're going to need one method we're going to call it function get audio stream and we're going to require a tag inside of here so we'll type underscore tag the type will be a string and then inside of here the first thing we're going to do is Define an index we're going to set it toga1 and then we're going to check if our tag is valid if it is then we're going to Loop through the sound effects so say for sound in sound effects and then we'll increase the index by one so say index plus equals whoops index plus equals 1 and then we'll check if our sound. tag is equal to our underscore tag then we will break and then after we break we will simply return sound effects and the index will be index and the value is going to be stream now we also want to check else so we're going to say else which means that our tag is not valid we are going to print error and it will say no tag provided cannot get sound effect and this would obviously mean that we do not have an audio stream to return so if we get to this point we're going to return null and now that we have these two classes defined we need to actually utilize them so we're going to make a new scene at the top it's going to be an other node and we're going to search for an audio stream player 2D and I'm going to name this one polyic audio player and we will save it inside of our scenes folder and we're going to add a script to this object and we're going to save it inside of our scripts folder and there's a couple things we need to do inside of here so first off we need to export a variable called audio library and the type will be our audio library class we then need to call the ready function so we'll say function ready and inside of here we simply want to define a new polyphonic audio player as the stream so we're going to say stream equals audio stream polyphonic new and next we want to set the polyon value of this new object so in this case it defaults to 32 and that's usually fine but we're going to make a new export variable we're going to call it Max polyon and it's going to be an INT and it will start at 32 and then we simply set stream. polyon equal to our Max save that and I guess this value is already defined so we're going to say custom and then we will set max polyon to custom Max polyon now we can reset this value as this was just for demonstration purposes but we will need a single method inside of this polyphonic audio player and we're going to call this method play sound effect from library and we will require a tag once again we're going to say underscore tag set this to a string and this method is going to return void now first up we would like to check if our tag is valid if it is then we can retrieve the audio stream but we' like to store it inside of a variable so we're going to say VAR audio stream and we'll set this equal to audio library. get audio stream and we will require our tag which is right here next up we need to check if our audio stream is already playing if it is not playing we need to start it otherwise if we try to get the stream playb when it's not playing it will return null and the game will crash so we would like to check if not playing then we are going to say self. playay and this will ensure that we're always playing the audio next up we need to store our stream playback so we say VAR polyphonic stream whoops polyphonic stream playback and we are going to set this one equal to self. getet stream uncore playback and the last thing we need to call inside of this method is simply the Polyphonic stream playback and inside of here we will call playcore stream and we need a value which is the stream which we've obtained up here so we simply put audio stream inside of that function and everything should work as intended now we can also add some quality of life feature here so we're going to say else once again and we will print on error which is no tag provided cannot play sound effect and this is just for the user now this is the last script that we'll need to Define so what we're going to do is create a few examples for this so I'm going to go into my Game World and I'm going to select the player and we're going to add a child node to this player and it's going to be our polyphonic AUD player. tscn and this is the scene that you'll want to instance if you would like to play overlapping audio or use audio libraries in this way so once we've instance this all we do is go to the audio library property and we select a new audio library and inside of our player sound effects we can just add a ton of new sound effect entries and we are going to drag in all of our sound effects so I'm going to make a new sound effect called checkpoints and I will load up my checkpoint checkpoint sound we're going to make another entry we're going to call this one jump and I will load up my jump sound and we'll make one more here I think we I have a take damage yeah so I have a enemy hit so we're going to say take damage and we will load up this enemy hit now as you can see from this already if we change the name or move any of our sound effects they will still be valid as we are looking them up inside of the resource so this way you don't have to worry about going back into your player script and changing all your constants or preloads or whatever and this is a lot more efficient in my opinion now this will also play overlapping audio obviously like I said and it won't be limited to just a single stream property but you'll be able to play all of these sound effects at the same time overlapping so how do we we actually play these sound effects well I'm going to make a new script on the player I'm going to put this in the scripts folder so we're going to go into our script and then we're going to go into our scene view hold control and drag in this polyphonic audio player so then we now have a reference to it and all we're going to do is say function uncore input event and we're going to null out the event but we're going to check if if inputs class dot is action just Prest and we're going to say play audio then we will simply call polyphonic audio player Dot and we got to remember the name of the function which is play sound effect from library and the sound effect we're going to play will just be a tag which will be jump and since I also have this object playing audio I'm just going to delete this for now and now we can see that if we run the game we can play the jump sound effect and it overlaps but it's essentially as easy as that we just need to pass in the jump key and it will reference our audio libraryies correct sound effect that has the jump key attached to it and get the stream so let's say we had a new sound effect for the jump that we wanted to load in we could simply just replace it here with something like the shoot sound effect I don't know why you'd want to do that but now it will play the shoot sound and like I said before you can play multiple audio streams at the same time so we could copy this line for now just cuz I don't want to set up any more inputs but let's say we played the sound effect for checkpoint we'll copy that key paste it in the function and when we play this now it will play two sound effects at the same time only using a single audio player node so that's about it for this video if you have any any ways of optimizing the system make sure to leave them in the comments I have tried a few different systems for playing audio in the past and this one is by far my favorite currently but again with this method let's say you had which I actually set up for this example I just never got to them but in the enemy class you could do something like def find some tags which are common for like enemy hits or enemy sound effects and then for each different enemy in its polyphonic audio player you could simply change its resources up and you might even want to move the audio library value into the actual node and then that might be a bit more efficient for something like this but you can mess around with this and kind of come up with your own system this is kind of just a base for an idea and also just an example of how to use this audio stream polyphonic class as the documentation doesn't really have a lot of coverage but thanks for watching the video and hope you learned something new if you did consider leaving a like and subscribing and also make sure to join the Discord server Link in the description anyways see you in the next one bye
Info
Channel: Queble
Views: 483
Rating: undefined out of 5
Keywords: programming, coding, godot, game, game dev, indie, program, software, editor, system, tutorial, Godot 4, script, button, math, animation, delta, time, informative, quick, easy, fast, education, course, 3d, custom, resource, audio, sound effects, background, overlapping, polyphonic, polyphony
Id: llJa2w8v1-M
Channel Id: undefined
Length: 16min 6sec (966 seconds)
Published: Thu Mar 21 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.