Search Unity

Question [Audio] Keeping pitch independent for different sounds/music in a 2D game

Discussion in 'Getting Started' started by BrusintP, Dec 1, 2021.

  1. BrusintP

    BrusintP

    Joined:
    Mar 19, 2020
    Posts:
    2
    Hi everyone!

    So I'm working on a small 2D game project, a bullet hell. I want to play a hit sound effect every time the character is hit by a bullet. Also, I want this sound effect to randomly vary its pitch everytime this happens, to add a bit of variability. For those functions I have the following code:

    This class initializes the static AudioManager class.
    Code (CSharp):
    1. public class GameAudioSource : MonoBehaviour
    2. {
    3.     private void Awake()
    4.     {
    5.         if(!AudioManager.Initialized)
    6.         {
    7.             //initialize audio manager and persist audio source across the game
    8.             AudioSource audioSource = gameObject.AddComponent<AudioSource>();
    9.             AudioSource musicSource = gameObject.AddComponent<AudioSource>();
    10.             AudioManager.Initialize(audioSource, musicSource);
    11.             DontDestroyOnLoad(gameObject);
    12.         }
    13.         else
    14.         {
    15.             //duplicate game object, so destroy
    16.             Destroy(gameObject);
    17.         }
    18.     }
    19. }

    This static class manages all audio and is called from other classes when required:
    Code (CSharp):
    1. public static class AudioManager
    2. {
    3.     static bool initialized = false;
    4.     static AudioSource audioSource;
    5.     static AudioSource musicSource;
    6.     static Dictionary<AudioClipName, AudioClip> audioclips = new Dictionary<AudioClipName, AudioClip>();
    7.  
    8.     public static bool Initialized
    9.     {
    10.         get { return initialized; }
    11.     }
    12.    
    13.     public static void Initialize(AudioSource source, AudioSource soundtrackSource)
    14.     {
    15.         initialized = true;
    16.         audioSource = source;
    17.         musicSource = soundtrackSource;
    18.         audioclips.Add(AudioClipName.Hit01, Resources.Load<AudioClip>("Sounds/Hit 01"));
    19.         audioclips.Add(AudioClipName.Hit02, Resources.Load<AudioClip>("Sounds/Hit 02"));
    20.         audioclips.Add(AudioClipName.RecoveringHealth, Resources.Load<AudioClip>("Sounds/RecoveringHealth"));
    21.         audioclips.Add(AudioClipName.FOX, Resources.Load<AudioClip>("Sounds/Music/FOX"));
    22.  
    23.     }
    24.     public static void Play(AudioClipName name)
    25.     {
    26.         audioSource.pitch = 1f;
    27.         audioSource.PlayOneShot(audioclips[name]);
    28.     }
    29.  
    30.     public static void PlayMusic(AudioClipName name)
    31.     {
    32.         musicSource.pitch = 1f;
    33.         musicSource.volume = 0.75f;
    34.         musicSource.PlayOneShot(audioclips[name]);
    35.     }
    36.     public static void PlayWithRandomPitch(AudioClipName name)
    37.     {
    38.         audioSource.pitch = 1f;
    39.         AudioClip clip = audioclips[name];
    40.         float pitchNumber = Random.Range(0.75f, 1.5f);
    41.         audioSource.pitch = pitchNumber;
    42.         audioSource.PlayOneShot(audioclips[name]);  
    43.     }
    44.     public static void PlayWithCustomPitch(AudioClipName name, float pitchNumber)
    45.     {
    46.         audioSource.pitch = 1f;
    47.         audioSource.pitch = pitchNumber;
    48.         audioSource.PlayOneShot(audioclips[name]);
    49.     }
    50. }

    My problem is this: when the game is playing a soundtrack and the character is hit by a bullet, the variation in pitch affects the soundtrack too, not only the "hit" sound effect. As it can be seen in the code, I tried using two different AudioSource components, one for sound effects and another for the soundtrack, but the problem persists. I'm not an expert at all on coding nor sound editing, so maybe I made a mistake I'm not catching.

    Any ideas? Thanks in advance : )
     
  2. JoeStrout

    JoeStrout

    Joined:
    Jan 14, 2011
    Posts:
    9,859
    It appears you've got two different AudioSource components on the same GameObject. Don't do that. Put each one on its own GameObject.

    Moreover, in a bullet hell game, I would imagine you often get hit with multiple bullets in the time it takes for the hit sound to play. So you really don't want a central AudioSource here. I would suggest you put it on the bullet instead. When the bullet hits, don't destroy it — hide the sprite or MeshRenderer or whatever it has, or switch to the hit effect, but keep the object in the scene. Call .Play on its AudioSource component (with the randomized pitch). And then only destroy the bullet after the sound has completed (the Destroy method has a handy "delay" parameter that makes this easy to do).
     
    hektorj and SparrowGS like this.
  3. BrusintP

    BrusintP

    Joined:
    Mar 19, 2020
    Posts:
    2
    Thank you so much! I was indeed putting two AudioSource in the same component. I'll try your approach to solve the issue : )