Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice

Question How to create sound controller that help us to get different sounds when clicked different object.

Discussion in 'Audio & Video' started by NjordNystrom, Nov 7, 2021.

  1. NjordNystrom

    NjordNystrom

    Joined:
    Feb 29, 2016
    Posts:
    25
    Hello folks, I m beginner at coding. As the title says how can i create sound controller like that.

    For instance, there is a farm and its include animals like cow, chicken and dog.

    When i click dog it must play sound "dogSound".

    When i click chick it must play sound "chickSound".

    Is there any idea how to create this. Thank you.
     
  2. thecloudkeeper

    thecloudkeeper

    Joined:
    Sep 21, 2021
    Posts:
    28
    Yeah, here's one example solution using Scriptable Objects:

    Sound.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. // Go to Assets -> Create -> Custom Assets -> Sound. Then assign your AudioClip to the new Sound that was created in the Project window.
    4. // Set your preferred volume level and choose whether you want it to loop or not.
    5. [CreateAssetMenu(fileName = "Sound", menuName = "Custom Assets/Sound", order = 0)]
    6. public class Sound : ScriptableObject
    7. {
    8.     public AudioClip audioClip;
    9.     [Range(0, 1)] public float volume = 1f;
    10.     public bool loop;
    11. }
    12.  
    SoundButton.cs
    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. // Add this component to your GameObject that you want to be clickable. Also, add a Collider2D, such as a BoxCollider or a CircleCollider.
    4. [RequireComponent(typeof(Collider2D))]
    5. public class SoundButton : MonoBehaviour
    6. {
    7.     // Assign the Sound Scriptable Object asset you've created that you want this button to play to this field.
    8.     [SerializeField] private Sound sound;
    9.  
    10.     // Unity only calls this method when a Collider2D is clicked, hence the need for that component.
    11.     private void OnMouseDown()
    12.     {
    13.         SoundController.Instance.PlaySound(sound);
    14.     }
    15. }
    16.  
    SoundController.cs
    Code (CSharp):
    1. using System.Collections.Generic;
    2. using UnityEngine;
    3.  
    4. // Create an empty GameObject in your scene and add this component to it.
    5. public class SoundController : MonoBehaviour
    6. {
    7.     // Lazy Singleton implementation. Use with caution: Does not handle duplicates, not thread-safe, etc.
    8.     // This is here so all SoundButton instances can call SoundController.PlaySound without having to store their own references to this class.
    9.     public static SoundController Instance
    10.     {
    11.         get
    12.         {
    13.             if (instance == null)
    14.                 instance = FindObjectOfType<SoundController>();
    15.  
    16.             return instance;
    17.         }
    18.     }
    19.  
    20.     private static SoundController instance;
    21.  
    22.     private readonly Dictionary<Sound, AudioSource> audioSources = new Dictionary<Sound, AudioSource>();
    23.  
    24.     public void PlaySound(Sound sound)
    25.     {
    26.         // If we already have this Sound in our audioSources Dictionary, play the prepared AudioSource.
    27.         // Otherwise, we add and load a new AudioSource.
    28.         if (!audioSources.TryGetValue(sound, out AudioSource audioSource))
    29.             audioSource = AddAudioSource(sound);
    30.  
    31.         PlayAudioSource(audioSource);
    32.     }
    33.  
    34.     private void PlayAudioSource(AudioSource audioSource)
    35.     {
    36.         // You could add a return statement instead of audioSource.Stop here if you don't want sounds cutting out and restarting on repeated clicks.
    37.         if (audioSource.isPlaying)
    38.             audioSource.Stop();
    39.  
    40.         audioSource.Play();
    41.     }
    42.  
    43.     private AudioSource AddAudioSource(Sound sound)
    44.     {
    45.         // Create a new AudioSource on the SoundController GameObject.
    46.         AudioSource audioSource = gameObject.AddComponent<AudioSource>();
    47.  
    48.         // Add a Key-Value pair to the audioSources Dictionary so we can play it again without adding a new AudioSource.
    49.         audioSources.Add(sound, audioSource);
    50.  
    51.         // Set AudioSource properties based on Sound object.
    52.         audioSource.clip = sound.audioClip;
    53.         audioSource.volume = sound.volume;
    54.         audioSource.loop = sound.loop;
    55.  
    56.         return audioSource;
    57.     }
    58. }
    59.  
    Let me know if you have any questions and I'd be more than happy to answer them!
     
    Last edited: Nov 7, 2021
    NjordNystrom likes this.
  3. NjordNystrom

    NjordNystrom

    Joined:
    Feb 29, 2016
    Posts:
    25

    Heyy thanks for your reply. i was at my grandmama home. When i have time i will reply you. Thanks for your time <3
     
    thecloudkeeper likes this.
  4. NjordNystrom

    NjordNystrom

    Joined:
    Feb 29, 2016
    Posts:
    25
    Basically main idea is creating Scriptable Objects to controll all changes in sounds. Then we are creating SoundButton.cs to adjust the conditions for playing sounds. SoundController.cs is where we are creating instance and control. I hope im not wrong at this point.

    I think you write very clear and good script. I'm really happy and very very thank you !!.

    But there is a point im stuck.


    Code (CSharp):
    1.     // Assign the Sound Scriptable Object asset you've created that you want this button to play to this field.
    2.     [SerializeField] private Sound sound;
    i cant understand this part. Do i need apply Sound script (creating from custom assets>sound) to here.
    I cant apply anything here.
     
  5. thecloudkeeper

    thecloudkeeper

    Joined:
    Sep 21, 2021
    Posts:
    28
    You got it, exactly! So assuming that the Sound.cs Scriptable Object class is in your project and has successfully compiled, you can create a new
    Sound
    asset via the menus, by going to Assets -> Create -> Custom Assets -> Sound. That will create a
    Sound.asset
    file in your Project. Rename it whatever you want -- maybe give it the name of the sound it will play. Then if you select it, you can see its serialized properties in the Inspector window. Drag your AudioClip that you've imported to your project onto the
    Sound
    's Audio Clip field. Then select your Sound Button GameObject to which you attached the
    SoundButton
    component, and drag the
    Sound
    asset onto the
    SoundButton
    component's
    Sound
    field. Let me know if anything is still confusing and I'm happy to explain.
     
    NjordNystrom likes this.
  6. NjordNystrom

    NjordNystrom

    Joined:
    Feb 29, 2016
    Posts:
    25
    Great !! I couldn't pay attention. its work ! Now its work what i imagine and i m gonna learn new thing. Thank you for your help.
     
    thecloudkeeper likes this.