UNITY 2020 ADVANCED AUDIO MANAGER, Game Essentials (3/5)

Поділитися
Вставка
  • Опубліковано 11 вер 2024

КОМЕНТАРІ • 69

  • @RenaissanceCoders
    @RenaissanceCoders  4 роки тому +10

    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

    • @JovsValorant
      @JovsValorant 3 роки тому +1

      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

    • @caseyaydin8242
      @caseyaydin8242 3 роки тому

      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.

    • @gab_gallard
      @gab_gallard 3 роки тому

      The code in the repository has some minor differences from the code shown in this video. Why?

    • @romeogaming6424
      @romeogaming6424 2 роки тому

      Your code is beatiful, thanks for sharing!

  • @RenaissanceCoders
    @RenaissanceCoders  4 роки тому +10

    Apologies for the popping noise on my mic. Hope it isn't too much of a distraction!

  • @tapendrashahi2097
    @tapendrashahi2097 4 роки тому +18

    This is what I have been waiting for. Advanced tutorials. Thank you so much.

  • @frknklcsln
    @frknklcsln 4 роки тому +5

    This is the most comprehensive audio manager system I've found on the internet. I appreciate it a lot!

  • @TheReginaldBarris
    @TheReginaldBarris 2 роки тому +5

    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).

    • @Tidalley
      @Tidalley Місяць тому

      I feel the same way

  • @lifetheoryoptimal3297
    @lifetheoryoptimal3297 4 роки тому +3

    This is probably the best series I have watched in game design thus far. You deserve more views. Subscribed.

  • @adambruton6686
    @adambruton6686 2 роки тому

    40 minutes in, my bro starts flowing

  • @renatusdev
    @renatusdev 3 роки тому

    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!

  • @AFuller2020
    @AFuller2020 3 роки тому

    It's really amazing how crappy the Unity tutorials are from Unity, it's great we have individuals that can teach everyone, many thanks.

  • @dignifried5554
    @dignifried5554 4 роки тому

    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.

  • @superhardcode
    @superhardcode Рік тому

    best tutorial on clean audiomanagement i've seen yet. thank you!

  • @michaeltorruella188
    @michaeltorruella188 Рік тому

    Great video man. Extremely helpful.

  • @pitsa5000
    @pitsa5000 Рік тому

    I appreciate your way of teaching

  • @pawe5436
    @pawe5436 2 роки тому

    Thank you! I was looking for long for a tutorial like this!

  • @ashfid8987
    @ashfid8987 4 роки тому +1

    This is a great video! Also bud, whats that color theme?

  • @rogercrawfis
    @rogercrawfis 3 роки тому

    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.

  • @sergiomaldonadodelgado2944
    @sergiomaldonadodelgado2944 4 роки тому

    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.

    • @sergiomaldonadodelgado2944
      @sergiomaldonadodelgado2944 4 роки тому

      Also, how hard would be to implement a way to PAUSE a sound, and do these get affected by the game's timescale?

  • @spikedzzilm
    @spikedzzilm 2 роки тому

    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!

  • @maydonoznoz
    @maydonoznoz 3 роки тому

    I have to watch this a few times more

  • @CultyGame
    @CultyGame 2 роки тому

    pro tutorials, keep it up!

  • @bixarrio5251
    @bixarrio5251 3 роки тому

    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

    • @JovsValorant
      @JovsValorant 3 роки тому +1

      Would you mind sharing this in code

  • @vickdeweo4288
    @vickdeweo4288 4 роки тому

    Good timing I was working on an audio manager when this came up. Thank's.

  • @gab_gallard
    @gab_gallard 3 роки тому +1

    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.

  • @yandrako
    @yandrako 3 роки тому

    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!

  • @farisradieddine3015
    @farisradieddine3015 3 роки тому +1

    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 :)

  • @erretiacca
    @erretiacca 4 роки тому

    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?

  • @MisterTrayser
    @MisterTrayser 2 роки тому

    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?

  • @kelvindai1994
    @kelvindai1994 Рік тому

    I have a question, how do I change the SoundTrack whenever I change scene ?

  • @hotroddd1
    @hotroddd1 2 роки тому

    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.

  • @tleanvasner6866
    @tleanvasner6866 3 роки тому

    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)

  • @UnderdogDen
    @UnderdogDen 3 роки тому

    how can i make string names work with the code...seems a bit hard

  • @LesusGames
    @LesusGames 2 роки тому

    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.

  • @ruanxun9454
    @ruanxun9454 4 роки тому +1

    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
      @RenaissanceCoders  4 роки тому

      A custom editor tool could be created to manage the data and make it easier to look at.

    • @ruanxun9454
      @ruanxun9454 4 роки тому +1

      @@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?

  • @ramizmollah3685
    @ramizmollah3685 3 роки тому

    Thanks

  • @cubedev4838
    @cubedev4838 4 роки тому +1

    Amazing!! Amazing!! Amazing!!

  • @NowWeWake
    @NowWeWake 4 роки тому

    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?

  • @MusicBox.Melodies
    @MusicBox.Melodies 4 роки тому

    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!

    • @RenaissanceCoders
      @RenaissanceCoders  4 роки тому

      (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
      @rogercrawfis 3 роки тому +1

      @@RenaissanceCoders Why didn't you use a Dictionary instead of a HashTable to avoid this cast?

    • @WadeStar
      @WadeStar 3 роки тому +1

      @@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.

  • @Light-wz6tq
    @Light-wz6tq 3 роки тому

    okay but what if we have multiple enemies that can fire and they have the same fire sfx, and how do we cross-fade?

  • @yudnai5577
    @yudnai5577 3 роки тому

    Very Good Tutorial. i Like It.

  • @yudnai5577
    @yudnai5577 3 роки тому +2

    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.

    • @gab_gallard
      @gab_gallard 3 роки тому

      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.

    • @WheremyPoptart
      @WheremyPoptart 2 роки тому

      Yep the enum should be named differently cause AudioType is already an existing Unity class which will only further add to confusion.

  • @felo2991
    @felo2991 4 роки тому

    Amazing tutorials, thanks so much

  • @imranyafith4251
    @imranyafith4251 4 роки тому

    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!

    • @RenaissanceCoders
      @RenaissanceCoders  4 роки тому

      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.

  • @PakuBaku
    @PakuBaku 3 роки тому

    Thank you very much for your time and effort

  • @limerep7619
    @limerep7619 4 роки тому

    Very cool, thank you!

  • @JovsValorant
    @JovsValorant 3 роки тому

    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

    • @myggenmagnus
      @myggenmagnus 3 роки тому

      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
      @prec77ous 2 роки тому

      @@myggenmagnus Thanks, but the code isn''t working for me. Are the questionmarks supposed to be something else?

    • @myggenmagnus
      @myggenmagnus 2 роки тому

      @@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

    • @myggenmagnus
      @myggenmagnus 2 роки тому

      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;
      }
      }

  • @mademade5939
    @mademade5939 4 роки тому

    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

    • @RenaissanceCoders
      @RenaissanceCoders  4 роки тому

      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?

    • @mademade5939
      @mademade5939 4 роки тому

      @@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

  • @kalleandrejohansson6567
    @kalleandrejohansson6567 3 роки тому

    Can you use this system to implement randomly playing from a list of clips? To get some variation in the sounds played.

  • @nowenow1162
    @nowenow1162 4 роки тому

    good