Search Unity

Audio 2D - How to make it where sounds can only be heard within active camera range

Discussion in 'Audio & Video' started by MisterSkitz, Jul 15, 2019.

  1. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    458
    have a game where each room has its own camera. The player toggles the cameras on/off upon entering/exiting the room. However, I can hear the enemies, traps, and sounds from the other rooms even though the cameras are inactive.(Even stuff on the other side of the scene, very, very far away can be heard) What I'd like to accomplish is making it to where the sounds can only be heard when that room's camera audio listener is active. All sounds outside of that cameras audio listener shouldn't be heard. ( Basically the camera view should be the range of audio ) I'm using Unity and making a 2D game.

    How can I achieve this?

    What I've tried:
    -On the Audio Source: Volume Rolloff set to Linear Rolloff
    -Min Distance: 0.1
    -Max Distance: 0.2
     
  2. marc_tanenbaum

    marc_tanenbaum

    Unity Technologies

    Joined:
    Oct 22, 2014
    Posts:
    350
    Hi @Tim-Duval,

    There are a few things to unpack here.

    First, at its most basic, all sound goes through the AudioListener. The AudioListener represents your ears, so audio will sound as far away as the AudioListener is from those audio sources. So the very first question: is the AudioListener attached to a camera? Given your setup you might want to consider having an AudioListener on every camera. You can only have one active AudioListener in any scene, but since you're activating/deactivating the cameras, the listeners will match the activation/deactivation of each camera. (I don't actually recommend this...keep reading.)

    Next, I'm wondering why you have a camera for every room? Why not use Cinemachine and have a virtual camera for every room instead? I feel like this would simplify things, since you'd have just the one real camera, on which the AudioListener would live, and you'd get all the cool options Cinemachine provides for more engaging visuals (e.g., camera/player lag). Here's a video showing CM for 2D, just to give you some ideas...


    Finally, since Unity has no concept of rooms, no playing sound in your game is ever truly "off" – even if you can't hear it. Setting distances and rolloffs is not a good option, since that simply means you're wasting resources that you're not using and, as you've observed, making your life complicated with sounds you don't actually want to hear. I would definitely recommend establishing some notion of room "state" in your game, and then ensuring all sounds in a room are deactivated when the room state is not the room you're in.

    Hope that helps!
     
    MisterSkitz likes this.
  3. MisterSkitz

    MisterSkitz

    Joined:
    Sep 2, 2015
    Posts:
    458
    I haven't really learned much about the camera/audio functionality; it's something that I'm working on. I never heard of Cinemachine before but it looks really cool! The video was side-scroller and I didn't see anything about how to switch from virtual camera to virtual camera. However, I have tried to activate/deactivate the cameras and listeners at the same time but it failed to work.
    Code (CSharp):
    1. public class CamToggle : MonoBehaviour
    2. {
    3.     [SerializeField]
    4.     private Camera cam1;
    5.  
    6.  
    7.     private void Start()
    8.     {
    9.        
    10.         if (cam1.tag == "StartCam")
    11.         {
    12.             cam1.enabled = true;
    13.             cam1.GetComponent<AudioListener>().enabled = true;
    14.         }
    15.         else { cam1.enabled = false; cam1.GetComponent<AudioListener>().enabled = false; }
    16.     }
    17.  
    18.     private void OnTriggerEnter2D(Collider2D collision)
    19.     {
    20.         if(collision.tag == "Player")
    21.         {
    22.             cam1.enabled = true;
    23.             cam1.GetComponent<AudioListener>().enabled = true;
    24.         }
    25.        
    26.     }
    27.  
    28.     private void OnTriggerExit2D(Collider2D collision)
    29.     {
    30.         if (collision.tag == "Player")
    31.         {
    32.             cam1.GetComponent<AudioListener>().enabled = false;
    33.             cam1.enabled = false;
    34.         }
    35.      
    36.     }
    37. }

    Here's a video so you can actually see the camera change between rooms. about 1:10

    Note- I have the enemy sounds off but trust me, you'd hear them pinging off the walls every time they touch even though the camera's audio listener is off in that room. I'm trying to figure out how to limit audio to just within each room. Can the Cinemachine help with this?