Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Audio How to Make 3D Sounds Mono when Close to AudioListener?

Discussion in 'Audio & Video' started by Zullar, May 20, 2018.

  1. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    I have a top-down game.


    The audio listener is attached at the hero. 3D sounds are played at the source location.

    With regards to stereo and left/right volume everything is fine. If a monster is to the right of the hero then the volume comes out of the right speaker. If a monster is up or down then it's volume is equal in both speakers.

    Currently when I play a clip in 3D space I create an AudioSource at a position and assign clip & settings and then play it. The clip is not actually attached to the source object emitting the noise (i.e. the monster or hero) in order to ensure if the source object is destroyed the clip finishes rather than cuts out. However doing this can sometimes give small positional differences between my hero and the AudioSource clips played by the hero. This slight positional errors can cause the audio clip to play in the left or right speaker only even for your own hero. I would like audioClips played for my hero to be mono, not stereo s o that having a negligible 0.01 meter distance between audio source & listener doesn't make the clip jump between left & right speakers.

    Ideally I'd like to do something like this. If distance between audio source & listener < 0.5m then play as mono... otherwise play as stereo.

    Is there an easy way to do this? The only way I can think is to add a script that checks distance between AudioSource & Listener and adjusts SpacialBlend/Spread... but I'd hate to have to add this to every 3D audio clip in the game.

    Alternatively I could try and ensure the distance between source & listener is always exactly 0 for my hero's clips and then it will play as mono. But not sure how best to do this the way things are currenly configured.

    Is there a proper way to handle this issue? Any thoughts? Thanks.
     
    Docaroo likes this.
  2. Docaroo

    Docaroo

    Joined:
    Nov 7, 2017
    Posts:
    82
    You could actually do this using the "Spread" parameter for 3D sounds. The added benefit of this is that the spread also be changed with distance from audiosource exactly as you describe you need.

    A spread value of 180° will mean that the sound does not pan depending on the listener postion, just affects volume. A value of 0° means that the full 3D panning effect is applied. Simply make the spread 180° when the position is under x units! Something like my attached screenshot.

    Note than on the curve editor the spread value is just a float so 0.5 = 180°.
     

    Attached Files:

  3. Zullar

    Zullar

    Joined:
    May 21, 2013
    Posts:
    651
    Thanks! Using spread seemed to do the trick. For anybody who runs into this issue...

    This gives 2D sound within 0.5m, and full 3D sound outside 1m.
    Code (csharp):
    1.  
    2.         Keyframe[] keyFrameArray = new Keyframe[4];
    3.         keyFrameArray[0] = new Keyframe(0, 0.5f);
    4.         keyFrameArray[1] = new Keyframe(0.5f, 0.5f);
    5.         keyFrameArray[2] = new Keyframe(1f, 0f);
    6.         keyFrameArray[3] = new Keyframe(maxDistanceIn, 0f);
    7.         AnimationCurve animationCurve = new AnimationCurve(keyFrameArray);
    8.         myAudioSource.SetCustomCurve(AudioSourceCurveType.Spread, animationCurve);
    9.  
    I had to match the last keyframe's x distance the audio sources max distance in order to keep the 0.5m and 1m distances absolute (otherwise they are relative w/r/t to the audio sources max distance). Also y value of 0.5 = 180deg (script uses 0-1 values and the inspector uses 0-360deg).
     
  4. Docaroo

    Docaroo

    Joined:
    Nov 7, 2017
    Posts:
    82
    Such a comment problem with Unity and audio parameters ... you can tell it's all written by programmers :)

    Everything is a 0-1 float and the audio parameters are all over the place ... like 0-360deg, -80 -> 0db etc... Frequency is the absolute worst one because it's logarithmic and small tweaks low in frequency have big audible differents by translate to very minute float changes (like from 0.067 to 0.071) haha.... but we get by :)