All of the code from this series (Game Essentials) is available on GitHub - along with some other stuff. Feel free to contribute. github.com/coderDarren/UnityCore
You all prolly dont care but does anyone know of a trick to get back into an Instagram account? I was dumb forgot the password. I appreciate any tricks you can offer me.
Overall a really good tutorial--thanks so much! For constructive feedback: There were times when I felt it got a bit complicated mostly because I just didn't understand exactly what we were trying to accomplish with a new step or I didn't understand how it fit in to the overall goal (Maybe that's because some parts were too advanced for me). It felt like, "do this, then this, then this then this, and....done!" I think it would have been a bit easier to follow if it were presented as "Here's how you get the audio sources up and running at the most basic level." Then once that's been explained, "But you see how it's allowing multiple sources from the same track to play? Here's how we prevent that." Then there's a clearer delineation between the fundamental steps and the advanced steps, and we can fully see the basic framework and then better follow how that framework is expanded upon as we go. Whereas it feels to me like you ordered it in the way that's most pragmatic if you already know what you're doing, but a bit harder to follow along (for me). I often found myself writing the code alongside you, but not being completely sure why the code was like that, and then I'd have to watch further, before going back to re-contextualize earlier steps. And since there were so few instances where the code was in a runnable state to see it in action and understand the progress, I struggled to know how near or far we were from the goal at any point in time. Again, I thought it was a really informative tutorial, and I really appreciate it. But in case you still care about constructive feedback 2 years later, these are just some thoughts that might help with clarity in future videos for a wider audience (of broader skill ranges).
I love that you have introduced me to like.. "programming for people". I've mainly done things myself, and I've heard about coding like mentioned, but now it opens my eyes how elegant it is when one programs for people like you have (namespaces, custom logs, etc.); cuz technically you are also programming for yourself. Ty!
Bravo. This series serves double duty for people (like me) who perpetually struggle with project design. I have always been impressed with how you organize your work, but the Unity folder system and your code in this series are the best example of project structuring I have ever seen.
Thanks for the tutorial. Really helped understand your code. On the teaching style, perhaps a second video on how to use the Github code base with many clips. Some coding comments / questions: The AudioController is a Singleton, but never really used as one. The array of AudioObjects {AudioType,AudioClip pairs} requires that each AudioType is unique. The point of this is to disallow 2 clips in this track from playing at the same time. This disallows a cross-fade on a track. Not really sure what your use-case you were thinking here other than two ambient music tracks and perhaps redundant SFX's. Was thinking having multiple AudioControllers for the different enums might be a cleaner approach.
I do not understand 100% what is going on, but I don't think I need to tbh. These are great, I know how to use them, I was able to not only follow step by step, but document the code in a shorter way so other devs I make games with are able to use the Unity Core systems, love these.
Hey I love your tutorials, They have really helped me, but it would be awesome if you could add time blocks for each section you are going over, so we can esily go back and see if we missed anything durring that implimentation. With my settings, by defalt in visual studios, and your style of coding, its somtimes hard to tell if the error is because I made a mistake, or if you just havent implemented it yet. But all-in-all, yyour content is great, thank you so much for putting this out to the community!
So happy to have found these! Just some comments; I know that there won't be loads of jobs running at the same time, but you might benefit from moving the _audioTrackNeeded code out of the foreach loop since it doesn't change, and you don't need to load it on every iteration. Also, when the fade loop is complete, your volume isn't necessarily equal to the target. You should set it to target once you are outside the loop. Then a question; Again, I understand these are basic and for your specific requirements, but how would you handle spatial sound? Would you create a soundtrack on the object where the sound is coming from? Anyway, love this tutorial. Looking forward to more
Thanks for the tutorial. Really useful. I have two questions. 1) How would you go about routing each AudioType to a different Mixer Group? I would like to group the audio sources in different categories to control their volumes from the mixer and not from the clips themselves. 2) I would also like to implement a random pitch range for certain AudioTypes (like footsteps, for example). How would you do that within this system? Thank you once more.
Thank you for such a professional and well explained audio manager system. How would you adapt the system for a game that could have few units fighting at the same time with their sound effects? (f.e Clash Royale). Would you have an dynamic list of possible audio tracks and fill them with clips if empty or..? Looking forward to watch the rest of your tutorials!
How can you make this a DontDestroyOnLoad? I tried it but it gave me a null reference error when the AudioManager script calls the Dispose Function. Any help would be greatly appreciated :)
Great approach, but I still have doubts on how to handle audioclips from Scriptable Object that change regularly at runtime. Is it good to put them in the AudioController (via functions, and then update them when the Scriptable Object is changed) or should I handle it in another way?
hi) could you tell me, please, where could I read more about #if and #ifelse - I understand vaguely what it's should be doing, but I want to find out more about Unity_Editor stuff) does #if has a name? cheers)
Just want to say, please do not dumb these tutorials down. Yes, it does get complicated, but I've learned more from this one tutorial then a bunch of videos from more popular Unity UA-camr videos combined. But I'd rather an hour and half long tutorial video (That takes 3 hours to get through because I'm always pausing to look other stuff up like... like hashables for example), then a 15 minute video that gives the bare basics to get something to work with a bunch of bad habits and minimum understanding. One bit of advice tho, when using something slightly more advanced, without having to go into the topic in great detail, perhaps just say 'If you don't understand what a hashable is, take a pause and read up on it', with perhaps a link in the description or something. But honestly mate, teach things HOW it should be done.. It's our responsibility to fill in the blanks on the WHY. (Otherwise the video would be 6 hours long, and you'll forever be repeating yourself in every video you make one. With that said, using this one video I've been able to create my own audio system that I can now just throw into any of my future projects. Appreciate the effort.
I have a question. When there are too much sounds added to the game, then there will be hundreds or thousands of AudioType. In this case, assigning one AudioType to an AudioObject will be a headache in the inspector because we have to look through all the AudioType, do you have some ideas how to solve it?
@@RenaissanceCoders Haha, thanks. What do you think about dealing with loop sound? For example, for soundtrack or running sound, I would like them to loop. Will you specify those looping property the same way like you add the fading effect? Or would you do it in another way?
Excellent video! I've followed along and created my own AudioController. I've put AudioTracks as scriptable objects so I can easily make collections of audio files in the editor with a custom inspector and then assign them to the AudioController. One question: Is Dispose() necessary? Aren't all coroutines attached to a gameObject stopped when the gameObject is disabled?
Thank you for this deep dive into sound! I personally do not fully understand your code, it is the first time I use Hashtables and I cannot understand some of your syntax i.e. " AudioTrack _track = (AudioTrack)m_AudioTable[_job.type]; . I don't get why we need (AudioTrack) in parenthesis and I don't know how to look that online.
Regarding your teaching style, it would be great to know if you are expecting the viewers to write along you (as I did), in case you want that, you should not talk while you write to give time to the listener to write too. Thank you for everything!
(AudioTrack) is a type cast. Hashtables are generic collections, so the runtime doesn't automatically know the value inside the hashtable is of type AudioTrack - we must specify using a type cast.
@@rogercrawfis It's just convention, probably depending on your coding background. However, you're right, in C# Dictionary is better in most cases because it allows generics and removes the need for casting. However, for other languages this code style is more conventional looking. Every language has a hash table and casting. Not every language has Dictionary. He might not have wanted to derail into an explanation of Dictionary and generics assuming that most people would understand casting and hash tables.
you are using AudioType !!! for me Audio Type is: MP3,WAV,Ogg,IFF..ect.. its need to be AudioName. less confusing. so AudioTypes will be reserved for when you want different types of the same Audio. like ST_01.WAV ST_01.mp3 ST_01.ogg and so on. (Sometimes you want High quality and sometimes less). especially with Games Like Geometry Dash Style for example.
Those (.wav, .mp3, .ogg) are called audio file formats btw. Unity has its own audio format conversion settings. In the best-case scenario, you should import lossless audio. Unity will standardize the format and compression settings for you. Is not a good idea to mix different audio formats together because they all will have different sample rates and sample depths which could create problems along the way. Is better to let Unity organize your file formats in a way that is consistent and organized.
I absolutely love this advanced kind of tutorial style, but one thing I don't quite understand is why you have separate audio tracks. Why is it necessary to make sure that one audio track only plays one audio clip at a time? What if I want two sound effects playing at the same time? Would I just make a new audio track in that case? I'm sorry if this is a dumb question but I just can't quite wrap my head around the "why". Thanks!
You can think of an audio track as an audio source. If you want two audio clips to play simultaneously,you need two tracks. It's a way of organizing your audio and various priority.
Probably way to late with this answer, but hopefully this will help if anyone else wants the same thing, I found a solution that worked for me, where I changed the "1"'s in the IEnumerator to variables: if (_job.fade) { float _volume = _track.source.volume; // gets the current volume of the selected track float _initial = _job.action == AudioAction.START || _job.action == AudioAction.RESTART ? 0.0f : _volume; float _target = _initial == 0 ? _volume : 0; ... // rest of the if-statement // then at the end of the statement: _track.source.volume = _volume } This has a bug where if you restart the same audioclip or start a new audioclip on the same track before the fade ends, the _volume will get the wrong value, but this can probably be fixed by setting this value another place (e.g. when you adjust the volume with the slider), but it's not an issue for me since I only use fade for longer clips.
@@prec77ous I was opening my last project where I used this to check it out (haven't been working on this for a while, so have forgotten a lot about this script), and found a few changes I had done. Firstly, I have added this function which is connected to the slider: public void AdjustVolumeIndex0(float _value) { if (tracks.Length == 0) { LogWarning("You are trying to change the volume on the track at index [0], but no track has this index"); return; } tracks[0].volume = _value; tracks[0].source.volume = _value; } For the next track, I used a new function where I changed (tracks.Length == 0) to (tracks.Length < 2) and all the [0] to [1] Then in the IEnumerator it looks like this: if (_job.fade) { float _initial = _job.action == AudioAction.START || _job.action == AudioAction.RESTART ? 0.0f : _track.volume; float _target = _initial == 0 ? _track.volume : 0; float _duration = 1.0f; float _timer = 0.0f; while (_timer
I made some other changes I did in the AudioTrack class and the function GenerateAudioTable() Just posting the entire class and function, so you can compare to yours. I might still have forgotten something, but I think this was all public class AudioTrack { public AudioSource source; [HideInInspector] public float volume; public float default_volume; public AudioObject[] audio; } private void GenerateAudioTable() { foreach (AudioTrack _track in tracks) { foreach (AudioObject _obj in _track.audio) { // do not duplicate keys if (m_AudioTable.ContainsKey(_obj.type)) { LogWarning("You are trying to register audio [" + _obj.type + "] that has already been registered."); } else { m_AudioTable.Add(_obj.type, _track); Log("Registering audio [" + _obj.type + "]."); } } _track.volume = _track.default_volume; _track.source.volume = _track.volume; } }
Hallo Darren please i really need your help, i did this tutorial twice already and end up in same mistake same situasion and i am still dont understand why, since i never learn hashtable before so the problem is when i do test Audio and press T for PlayAudio i got a messsage say [Audio Controller]: Starting job on [NONE] with operation START and this is my AddJob function: private void AddJob(AudioJob _job) { // remove conflicting jobs RemoveConflictingJob(_job.type); // start job IEnumerator _jobRunner = RunAudioJob(_job); m_JobTable.Add(_job.type, _jobRunner); Log("Starting job on [" + _job.type + "] with operation " + _job.action); } its completely same as your right? and now this is My RunAudioJob IEnumerator private IEnumerator RunAudioJob(AudioJob _job) { AudioTrack _track = (AudioTrack)m_AudioTable[_job.type]; _track.source.clip = GetAudioClipFromAudioTrack(_job.type, _track); switch (_job.action) { case AudioAction.START: _track.source.Play(); break;
case AudioAction.STOP: _track.source.Stop(); break;
case AudioAction.RESTART: _track.source.Stop(); _track.source.Play(); break; } m_JobTable.Remove(_job.type); Log("Job count: " + m_JobTable.Count); yield return null; } Any solution?? please i really love the way your system, maybe i can still implemented your system by look at your Make Game every month tutorial but if i know the idea how the system work i believe i can chane i need to and now im end up with this problem
Well the message says you are trying to start job NONE. Remember there is an AudioType enumeration. What are you passing into the audioCotnroller.PlayAudio() function from the testing script?
@@RenaissanceCoders and this is to PlayAudio method inside Audio Controller class public void PlayAudio(AudioType _type) { AddJob(new AudioJob(AudioAction.START, _type)); } this is inside test Audio if (Input.GetKeyUp(KeyCode.T)) { audioController.PlayAudio(AudioType.ST_01); } and inside core system game object i did pass what it need there i believe
All of the code from this series (Game Essentials) is available on GitHub - along with some other stuff. Feel free to contribute. github.com/coderDarren/UnityCore
I came across this problem where i want a settings slider that could adjust the volume but the lerp code keeps messing with it so how do i fix that
You all prolly dont care but does anyone know of a trick to get back into an Instagram account?
I was dumb forgot the password. I appreciate any tricks you can offer me.
The code in the repository has some minor differences from the code shown in this video. Why?
Your code is beatiful, thanks for sharing!
Apologies for the popping noise on my mic. Hope it isn't too much of a distraction!
This is what I have been waiting for. Advanced tutorials. Thank you so much.
This is the most comprehensive audio manager system I've found on the internet. I appreciate it a lot!
Overall a really good tutorial--thanks so much!
For constructive feedback: There were times when I felt it got a bit complicated mostly because I just didn't understand exactly what we were trying to accomplish with a new step or I didn't understand how it fit in to the overall goal (Maybe that's because some parts were too advanced for me).
It felt like, "do this, then this, then this then this, and....done!" I think it would have been a bit easier to follow if it were presented as "Here's how you get the audio sources up and running at the most basic level." Then once that's been explained, "But you see how it's allowing multiple sources from the same track to play? Here's how we prevent that." Then there's a clearer delineation between the fundamental steps and the advanced steps, and we can fully see the basic framework and then better follow how that framework is expanded upon as we go.
Whereas it feels to me like you ordered it in the way that's most pragmatic if you already know what you're doing, but a bit harder to follow along (for me). I often found myself writing the code alongside you, but not being completely sure why the code was like that, and then I'd have to watch further, before going back to re-contextualize earlier steps. And since there were so few instances where the code was in a runnable state to see it in action and understand the progress, I struggled to know how near or far we were from the goal at any point in time.
Again, I thought it was a really informative tutorial, and I really appreciate it. But in case you still care about constructive feedback 2 years later, these are just some thoughts that might help with clarity in future videos for a wider audience (of broader skill ranges).
I feel the same way
This is probably the best series I have watched in game design thus far. You deserve more views. Subscribed.
40 minutes in, my bro starts flowing
I love that you have introduced me to like.. "programming for people". I've mainly done things myself, and I've heard about coding like mentioned, but now it opens my eyes how elegant it is when one programs for people like you have (namespaces, custom logs, etc.); cuz technically you are also programming for yourself. Ty!
It's really amazing how crappy the Unity tutorials are from Unity, it's great we have individuals that can teach everyone, many thanks.
Bravo. This series serves double duty for people (like me) who perpetually struggle with project design. I have always been impressed with how you organize your work, but the Unity folder system and your code in this series are the best example of project structuring I have ever seen.
best tutorial on clean audiomanagement i've seen yet. thank you!
Great video man. Extremely helpful.
I appreciate your way of teaching
Thank you! I was looking for long for a tutorial like this!
This is a great video! Also bud, whats that color theme?
Thanks for the tutorial. Really helped understand your code. On the teaching style, perhaps a second video on how to use the Github code base with many clips. Some coding comments / questions: The AudioController is a Singleton, but never really used as one. The array of AudioObjects {AudioType,AudioClip pairs} requires that each AudioType is unique. The point of this is to disallow 2 clips in this track from playing at the same time. This disallows a cross-fade on a track. Not really sure what your use-case you were thinking here other than two ambient music tracks and perhaps redundant SFX's. Was thinking having multiple AudioControllers for the different enums might be a cleaner approach.
I do not understand 100% what is going on, but I don't think I need to tbh. These are great, I know how to use them, I was able to not only follow step by step, but document the code in a shorter way so other devs I make games with are able to use the Unity Core systems, love these.
Also, how hard would be to implement a way to PAUSE a sound, and do these get affected by the game's timescale?
Hey I love your tutorials, They have really helped me, but it would be awesome if you could add time blocks for each section you are going over, so we can esily go back and see if we missed anything durring that implimentation. With my settings, by defalt in visual studios, and your style of coding, its somtimes hard to tell if the error is because I made a mistake, or if you just havent implemented it yet.
But all-in-all, yyour content is great, thank you so much for putting this out to the community!
I have to watch this a few times more
pro tutorials, keep it up!
So happy to have found these!
Just some comments; I know that there won't be loads of jobs running at the same time, but you might benefit from moving the _audioTrackNeeded code out of the foreach loop since it doesn't change, and you don't need to load it on every iteration. Also, when the fade loop is complete, your volume isn't necessarily equal to the target. You should set it to target once you are outside the loop.
Then a question; Again, I understand these are basic and for your specific requirements, but how would you handle spatial sound? Would you create a soundtrack on the object where the sound is coming from?
Anyway, love this tutorial. Looking forward to more
Would you mind sharing this in code
Good timing I was working on an audio manager when this came up. Thank's.
Thanks for the tutorial. Really useful. I have two questions. 1) How would you go about routing each AudioType to a different Mixer Group? I would like to group the audio sources in different categories to control their volumes from the mixer and not from the clips themselves. 2) I would also like to implement a random pitch range for certain AudioTypes (like footsteps, for example). How would you do that within this system? Thank you once more.
Thank you for such a professional and well explained audio manager system. How would you adapt the system for a game that could have few units fighting at the same time with their sound effects? (f.e Clash Royale). Would you have an dynamic list of possible audio tracks and fill them with clips if empty or..?
Looking forward to watch the rest of your tutorials!
How can you make this a DontDestroyOnLoad? I tried it but it gave me a null reference error when the AudioManager script calls the Dispose Function. Any help would be greatly appreciated :)
Great approach, but I still have doubts on how to handle audioclips from Scriptable Object that change regularly at runtime. Is it good to put them in the AudioController (via functions, and then update them when the Scriptable Object is changed) or should I handle it in another way?
If I have a large game with a lot of audio clips and sources, should I assign each of these to audio manager and make 100500 audio types? Is it ok?
I have a question, how do I change the SoundTrack whenever I change scene ?
I'm only 30 mins in but this is great. I'm wondering if it is possible to use Scriptable Objects with this system to handle managment/configuration.
hi) could you tell me, please, where could I read more about #if and #ifelse - I understand vaguely what it's should be doing, but I want to find out more about Unity_Editor stuff) does #if has a name? cheers)
how can i make string names work with the code...seems a bit hard
Just want to say, please do not dumb these tutorials down. Yes, it does get complicated, but I've learned more from this one tutorial then a bunch of videos from more popular Unity UA-camr videos combined. But I'd rather an hour and half long tutorial video (That takes 3 hours to get through because I'm always pausing to look other stuff up like... like hashables for example), then a 15 minute video that gives the bare basics to get something to work with a bunch of bad habits and minimum understanding. One bit of advice tho, when using something slightly more advanced, without having to go into the topic in great detail, perhaps just say 'If you don't understand what a hashable is, take a pause and read up on it', with perhaps a link in the description or something. But honestly mate, teach things HOW it should be done.. It's our responsibility to fill in the blanks on the WHY. (Otherwise the video would be 6 hours long, and you'll forever be repeating yourself in every video you make one.
With that said, using this one video I've been able to create my own audio system that I can now just throw into any of my future projects. Appreciate the effort.
I have a question. When there are too much sounds added to the game, then there will be hundreds or thousands of AudioType. In this case, assigning one AudioType to an AudioObject will be a headache in the inspector because we have to look through all the AudioType, do you have some ideas how to solve it?
A custom editor tool could be created to manage the data and make it easier to look at.
@@RenaissanceCoders Haha, thanks. What do you think about dealing with loop sound? For example, for soundtrack or running sound, I would like them to loop. Will you specify those looping property the same way like you add the fading effect? Or would you do it in another way?
Thanks
Amazing!! Amazing!! Amazing!!
Excellent video! I've followed along and created my own AudioController. I've put AudioTracks as scriptable objects so I can easily make collections of audio files in the editor with a custom inspector and then assign them to the AudioController.
One question: Is Dispose() necessary? Aren't all coroutines attached to a gameObject stopped when the gameObject is disabled?
Thank you for this deep dive into sound!
I personally do not fully understand your code, it is the first time I use Hashtables and I cannot understand some of your syntax i.e. " AudioTrack _track = (AudioTrack)m_AudioTable[_job.type]; . I don't get why we need (AudioTrack) in parenthesis and I don't know how to look that online.
Regarding your teaching style, it would be great to know if you are expecting the viewers to write along you (as I did), in case you want that, you should not talk while you write to give time to the listener to write too.
Thank you for everything!
(AudioTrack) is a type cast. Hashtables are generic collections, so the runtime doesn't automatically know the value inside the hashtable is of type AudioTrack - we must specify using a type cast.
@@RenaissanceCoders Why didn't you use a Dictionary instead of a HashTable to avoid this cast?
@@rogercrawfis It's just convention, probably depending on your coding background. However, you're right, in C# Dictionary is better in most cases because it allows generics and removes the need for casting. However, for other languages this code style is more conventional looking. Every language has a hash table and casting. Not every language has Dictionary. He might not have wanted to derail into an explanation of Dictionary and generics assuming that most people would understand casting and hash tables.
okay but what if we have multiple enemies that can fire and they have the same fire sfx, and how do we cross-fade?
Very Good Tutorial. i Like It.
you are using AudioType !!! for me Audio Type is: MP3,WAV,Ogg,IFF..ect.. its need to be AudioName. less confusing. so AudioTypes will be reserved for when you want different types of the same Audio.
like ST_01.WAV ST_01.mp3 ST_01.ogg and so on. (Sometimes you want High quality and sometimes less). especially with Games Like Geometry Dash Style for example.
Those (.wav, .mp3, .ogg) are called audio file formats btw. Unity has its own audio format conversion settings. In the best-case scenario, you should import lossless audio. Unity will standardize the format and compression settings for you. Is not a good idea to mix different audio formats together because they all will have different sample rates and sample depths which could create problems along the way. Is better to let Unity organize your file formats in a way that is consistent and organized.
Yep the enum should be named differently cause AudioType is already an existing Unity class which will only further add to confusion.
Amazing tutorials, thanks so much
I absolutely love this advanced kind of tutorial style, but one thing I don't quite understand is why you have separate audio tracks. Why is it necessary to make sure that one audio track only plays one audio clip at a time? What if I want two sound effects playing at the same time? Would I just make a new audio track in that case? I'm sorry if this is a dumb question but I just can't quite wrap my head around the "why".
Thanks!
You can think of an audio track as an audio source. If you want two audio clips to play simultaneously,you need two tracks. It's a way of organizing your audio and various priority.
Thank you very much for your time and effort
Very cool, thank you!
I came across this problem where i want a settings slider that could adjust the volume but the lerp code keeps messing with it so how do i fix that
Probably way to late with this answer, but hopefully this will help if anyone else wants the same thing, I found a solution that worked for me, where I changed the "1"'s in the IEnumerator to variables:
if (_job.fade) {
float _volume = _track.source.volume; // gets the current volume of the selected track
float _initial = _job.action == AudioAction.START || _job.action == AudioAction.RESTART ? 0.0f : _volume;
float _target = _initial == 0 ? _volume : 0;
...
// rest of the if-statement
// then at the end of the statement:
_track.source.volume = _volume
}
This has a bug where if you restart the same audioclip or start a new audioclip on the same track before the fade ends, the _volume will get the wrong value, but this can probably be fixed by setting this value another place (e.g. when you adjust the volume with the slider), but it's not an issue for me since I only use fade for longer clips.
@@myggenmagnus Thanks, but the code isn''t working for me. Are the questionmarks supposed to be something else?
@@prec77ous I was opening my last project where I used this to check it out (haven't been working on this for a while, so have forgotten a lot about this script), and found a few changes I had done.
Firstly, I have added this function which is connected to the slider:
public void AdjustVolumeIndex0(float _value) {
if (tracks.Length == 0) {
LogWarning("You are trying to change the volume on the track at index [0], but no track has this index");
return;
}
tracks[0].volume = _value;
tracks[0].source.volume = _value;
}
For the next track, I used a new function where I changed (tracks.Length == 0) to (tracks.Length < 2) and all the [0] to [1]
Then in the IEnumerator it looks like this:
if (_job.fade) {
float _initial = _job.action == AudioAction.START || _job.action == AudioAction.RESTART ? 0.0f : _track.volume;
float _target = _initial == 0 ? _track.volume : 0;
float _duration = 1.0f;
float _timer = 0.0f;
while (_timer
I made some other changes I did in the AudioTrack class and the function GenerateAudioTable() Just posting the entire class and function, so you can compare to yours. I might still have forgotten something, but I think this was all
public class AudioTrack {
public AudioSource source;
[HideInInspector] public float volume;
public float default_volume;
public AudioObject[] audio;
}
private void GenerateAudioTable() {
foreach (AudioTrack _track in tracks) {
foreach (AudioObject _obj in _track.audio) {
// do not duplicate keys
if (m_AudioTable.ContainsKey(_obj.type)) {
LogWarning("You are trying to register audio [" + _obj.type + "] that has already been registered.");
} else {
m_AudioTable.Add(_obj.type, _track);
Log("Registering audio [" + _obj.type + "].");
}
}
_track.volume = _track.default_volume;
_track.source.volume = _track.volume;
}
}
Hallo Darren please i really need your help, i did this tutorial twice already and end up in same mistake same situasion and i am still dont understand why, since i never learn hashtable before
so the problem is when i do test Audio and press T for PlayAudio i got a messsage say [Audio Controller]: Starting job on [NONE] with operation START and this is my AddJob function:
private void AddJob(AudioJob _job)
{
// remove conflicting jobs
RemoveConflictingJob(_job.type);
// start job
IEnumerator _jobRunner = RunAudioJob(_job);
m_JobTable.Add(_job.type, _jobRunner);
Log("Starting job on [" + _job.type + "] with operation " + _job.action);
}
its completely same as your right? and now this is My RunAudioJob IEnumerator
private IEnumerator RunAudioJob(AudioJob _job)
{
AudioTrack _track = (AudioTrack)m_AudioTable[_job.type];
_track.source.clip = GetAudioClipFromAudioTrack(_job.type, _track);
switch (_job.action)
{
case AudioAction.START:
_track.source.Play();
break;
case AudioAction.STOP:
_track.source.Stop();
break;
case AudioAction.RESTART:
_track.source.Stop();
_track.source.Play();
break;
}
m_JobTable.Remove(_job.type);
Log("Job count: " + m_JobTable.Count);
yield return null;
}
Any solution?? please i really love the way your system, maybe i can still implemented your system by look at your Make Game every month tutorial but if i know the idea how the system work i believe i can chane i need to and now im end up with this problem
Well the message says you are trying to start job NONE. Remember there is an AudioType enumeration. What are you passing into the audioCotnroller.PlayAudio() function from the testing script?
@@RenaissanceCoders
and this is to PlayAudio method inside Audio Controller class
public void PlayAudio(AudioType _type)
{
AddJob(new AudioJob(AudioAction.START, _type));
}
this is inside test Audio
if (Input.GetKeyUp(KeyCode.T))
{
audioController.PlayAudio(AudioType.ST_01);
}
and inside core system game object i did pass what it need there i believe
Can you use this system to implement randomly playing from a list of clips? To get some variation in the sounds played.
good