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. Dismiss Notice

What's the best way to do this? Audio Listener

Discussion in 'Editor & General Support' started by heronww, Sep 25, 2019.

  1. heronww

    heronww

    Joined:
    Sep 8, 2019
    Posts:
    24
    So new to Unity but experienced in programming, just got into the Audio section on the documentation. I see there are two recommended ways of placing audio listeners, either on the player object or the camera. Unfortunately from what I can tell in my limited experience so far these are both bad for the following reasons -

    1) Placing audio listener on the camera in a 3rd person view means that audio with 3D spatial blend (audio with distance) will be loud when the player is far from the object but the camera is over the object, which is highly unrealistic.

    2) The more realistic option placing the audio on the player seems to lead to a problem whereby every time the player rotates, the audio is heard from a different directional source. This would be fine for 1st person but not for 3rd person view. Setting the audio as non-directional (2D) is not a desired solution either as I desire for the player to be able to locate the direction of the audio.

    The simple solution so I thought would be to have an audio listener on top of the player that simply doesn't rotate. But there seems to be no way to do this without invoking an Update() somewhere. Creating an empty child object on the player but with an audio listener will cause the child listener to rotate just like the player does, so it makes no difference. The only solution I could think of is to make the child object "manually fight with the rotation" via a script, which seems incredibly inefficient by a factor of 2 (not only are we rotating the child object unnecessarilyy, we are also doing extra rotations to undo these unnecessary rotations, in a high cost method such as Update() of all places, which just feels very dirty to me from an optimization perspective).

    So currently this works for me fine, but it seems inefficient -
    1) Attach child object to player, with audio listener
    2) Attach the following script to the child object -

    Code (CSharp):
    1. public class FixedRotation : MonoBehaviour
    2.     {
    3.         void LateUpdate()
    4.         {
    5.             transform.rotation = Quaternion.Euler(Vector3.zero);
    6.         }
    7.     }
    That doesn't feel nice doing 60 odd allocations per update just to reverse a rotation I don't want. The other alternative is to make an object that simply follows the player but not as a child, but the same problem arises since we're still calling Update() each frame this time just via transform.position instead.

    The other solution I thought of was to attach a rigidbody to the empty object, and constrain all its rotational axis and Y positional axis.

    So my question is, which of the following is the least costly in terms of doing what I want?
    1) My current solution
    2) The rigidbody solution I propose
    3) Something simple I haven't thought about

    Thanks.
     
  2. XENA_SN

    XENA_SN

    Joined:
    Jan 8, 2020
    Posts:
    1
    I'm facing the exact same issue, the author of this post has detailed precisely my actual dilemma. Does anybody can help me (or us if he still hasn't found a solution) about this ?

    (Sorry for the small necropost but I thought it was better than creating a new thread for the exact same question as this is still non-answered )

    Thanks
     
  3. ibbybn

    ibbybn

    Joined:
    Jan 6, 2017
    Posts:
    193
    I honestly don't see how his solution could be improved, but I don't see it as inefficient at all.
    Setting one transform each frame is negligible. We're not in the 1980s anymore. ;)
    I would write Quaternion.identity instead of Quaternion.Euler(Vector3.zero).
    Or rather use the cameras rotation unless your game has a non rotating camera.
    Other than that you could just have the listener on a forward placed transform child of the camera if the camera is always at the same distance and doesn't collide.
     
    Joe-Censored likes this.
  4. Joe-Censored

    Joe-Censored

    Joined:
    Mar 26, 2013
    Posts:
    11,847
    I would just put the audio listener on a child on the player, then every LateUpdate set the child's world space rotation to the same as the camera object's rotation. So the audio listener will be at the player's location, but facing the same direction as the camera instead of the direction the player object is facing.

    I don't know why you're afraid to call Update or LateUpdate. You're not going to have thousands of this script in the scene. You're just going to have one of them.

    edit: sorry just realized I was responding to a necro, but my answer still applies
     
  5. GrimnirTheWhite

    GrimnirTheWhite

    Joined:
    Feb 9, 2019
    Posts:
    3
    Place the gameobject listener as child in camera, update delta distance ( player to camera) into audio listener position.