Make camera audio listener with FMODUnity

Hi, I'm a sound designer and cowboy programmer. By cowboy I mean show me how to do something and I can apply it to my own objects / set my own variables etc etc. This is beyond my experience but something tells me it should be possible.

I have been using some scripts created by another similar sound designer/programmer but obviously slightly better than myself!

He has created this script to tell FMOD where the player is relative to a sound emitter by passing it the 3D info about the player. Problem is, it was written for a 1st person game. I am making a platformer. Basically I need this to correspond to the Camera instead as, in a platformer, the camera is the audio listener. The stuff about footsteps etc I will need to keep on the actual player but I'm not so worried about that right now so edit that out (same with the wallpat etc). Could someone edit this script for me to be attached to the camera instead of the player so that FMOD can receive its 3D position info.

Here is some basic FMOD 3D Listener programmers (C++ not C# but should be similar) info:

EventSystem::set3DListenerAttributes This updates the position, velocity and orientation of the specified 3D sound listener.

C++ Syntax

FMOD_RESULT EventSystem::set3DListenerAttributes( int listener, const FMOD_VECTOR * pos, const FMOD_VECTOR * vel, const FMOD_VECTOR * forward, const FMOD_VECTOR * up );

C Syntax

FMOD_RESULT FMOD_EventSystem_Set3DListenerAttributes( FMOD_EVENTSYSTEM * eventsystem, int listener, const FMOD_VECTOR * pos, const FMOD_VECTOR * vel, const FMOD_VECTOR * forward, const FMOD_VECTOR * up );

Parameters

listener

Listener ID in a multi-listener environment. Specify 0 if there is only 1 listener.

pos

Address of a variable that receives the position of the listener in world space, measured in distance units. You can specify 0 or NULL to not update the position.

vel

Address of a variable that receives the velocity of the listener measured in distance units per second. You can specify 0 or NULL to not update the velocity of the listener.

forward

Address of a variable that receives the forwards orientation of the listener. This vector must be of unit length and perpendicular to the up vector. You can specify 0 or NULL to not update the forwards orientation of the listener.

up

Address of a variable that receives the upwards orientation of the listener. This vector must be of unit length and perpendicular to the forwards vector. You can specify 0 or NULL to not update the upwards orientation of the listener.

and the script in question (FMODPlayer.cs):

Code:

using UnityEngine; 
using System; 
using System.Collections; 
[RequireComponent (typeof (CharacterController))] 

public class FMODPlayer : MonoBehaviour { 
   private static FMOD.EventSystem    eventsystem = null; 
   private static FMOD.System system = null; 
    private FMOD.VECTOR   pos; 
    private FMOD.VECTOR   vel; 
    private FMOD.VECTOR   forward; 
    private int listener = 0; 
    private FMOD.VECTOR up; 
    private CharacterController me; 
   public string SoundController = "SoundControl"; 
   public float TurnStepThreshold = 80; 
   private FootstepsSound footsteps; 
   private WallPatSound wallsound; 
   private bool wastouchingwall = false; 
   private bool hasYelled = false; 
   private bool isStepping = false; 
   private bool inTrigger = false; 
   private bool wasMoving = true; 
   private float stepDirection; 
//   private Transform activePlatform; 
   private Vector3 activeLocalPlatformPoint; 
   private Vector3 activeGlobalPlatformPoint; 
   private Quaternion activeLocalPlatformRotation; 
   private Quaternion activeGlobalPlatformRotation; 

   void Start () { 
         me = GetComponent<CharacterController>(); 
         if (!GameObject.Find(SoundController)) 
         { 
            Debug.LogError("FMODsystem for FMODPlayer on "+this.transform.name+" not found!"); 
            Destroy(this); 
         } 
         else{ 
               FMODsystem SoundSystem = GameObject.Find(SoundController).GetComponent<FMODsystem>(); 
               eventsystem = SoundSystem.getEventSystem(); 
               //system = SoundSystem.getSystem(); 
         } 
         footsteps = GetComponent<FootstepsSound>(); 
         wallsound = GetComponent<WallPatSound>(); 

   } 

   void Update () { 
//      Debug.Log("I am ALIVE"); 
      pos = VectorConvert(this.transform.position); 
      Debug.Log("Playa Position is now " + pos.x + ", " + pos.y + ", "+ pos.z); 
      vel = VectorConvert(me.velocity); 
//      Debug.Log("Viewer speed should be " + me.velocity.magnitude);      
      forward = VectorConvert(this.transform.forward); 
      up = VectorConvert(this.transform.up); 
      FMOD.RESULT result = eventsystem.set3DListenerAttributes(listener, ref pos, ref vel, ref forward, ref up); 
//      result = system.set3DListenerAttributes(listener, ref pos, ref vel, ref forward, ref up);       
      ERRCHECK(result); 
      FMOD.VECTOR RealPos = VectorConvert(Vector3.zero); 
      eventsystem.get3DListenerAttributes(listener, ref RealPos, ref vel, ref forward, ref up); 
      //Debug.Log("Viewer velocity is now " + vel.x + ", " + vel.y + ", "+ vel.z); 
      //Debug.Log("Playa Position is now " + RealPos.x + ", " + RealPos.y + ", "+ RealPos.z); 
      //Debug.Log("Player speed is " + Mathf.Sqrt(Mathf.Pow(me.velocity.x,2)+Mathf.Pow(me.velocity.z,2))); 

//      if (me.collisionFlags == CollisionFlags.Sides) 
//      { 
//         //Debug.Log("Touching sides!"); 
//         if (!wastouchingwall){ 
//            footsteps.setWall(1f); 
//            wastouchingwall = true; 
//         }else 
//         { 
//            footsteps.setWall(me.velocity.magnitude/3); 
//         } 
//      }else{ 
//         footsteps.setWall(0); 
//         wastouchingwall = false; 
//      } 
      footsteps.setSpeed(me.velocity.magnitude); 
      footsteps.setPos(me.transform.position, me.velocity); 
      if(!isStepping) 
      { 
         footsteps.Begin(); 
      } 
      if (me.velocity.magnitude > 2.5 && wastouchingwall) 
      { 
         wastouchingwall = false; 
         hasYelled = false; 
         //Debug.Log("notWAlledanymore"); 
      } 
      if(wastouchingwall == false) 
      { 
         wallsound.setWall(0); 
      } 

      if(me.velocity.magnitude == 0) 
      { 
         if (wasMoving) 
         { 
            stepDirection = transform.eulerAngles.y; 
            wasMoving = false; 
         } 
         if(((stepDirection - transform.eulerAngles.y) > TurnStepThreshold) || ((stepDirection - transform.eulerAngles.y) < -TurnStepThreshold)) 
         { 
            footsteps.End(); 
            footsteps.setSpeed(1f); 
            footsteps.Begin(); 
            footsteps.setSpeed(0.01f); 
            //Debug.Log("I just stepped around"); 
            stepDirection = transform.eulerAngles.y; 
         } 
         footsteps.setSpeed(0.1f); 
      }else 
      { 
         wasMoving = true; 
      } 

   } 

   private void FixedUpdate() 
   { 
      if (!inTrigger && footsteps != GetComponent<FootstepsSound>()) 
      { 
         footsteps = SwitchSteps(me); 
      } 
    // Moving platform support 
//    if (activePlatform != null) { 
//        Vector3 newGlobalPlatformPoint = activePlatform.TransformPoint(activeLocalPlatformPoint); 
//        Vector3 moveDistance = (newGlobalPlatformPoint - activeGlobalPlatformPoint); 
//        if (moveDistance != Vector3.zero) 
//        { 
//           Debug.Log(moveDistance); 
//            transform.Translate(moveDistance); 
//        } 
// 
//        // If you want to support moving platform rotation as well: 
//        Quaternion newGlobalPlatformRotation = activePlatform.rotation * activeLocalPlatformRotation; 
//        Quaternion rotationDiff = newGlobalPlatformRotation * Quaternion.Inverse(activeGlobalPlatformRotation); 
// 
//        // Prevent rotation of the local up vector 
//        rotationDiff = Quaternion.FromToRotation(rotationDiff * transform.up, transform.up) * rotationDiff; 
// 
//        transform.rotation = rotationDiff * transform.rotation; 
//    } 
// 
//    activePlatform = null; 
// 
// 
//    // Moving platforms support 
//    if (activePlatform != null) { 
//        activeGlobalPlatformPoint = transform.position; 
//        activeLocalPlatformPoint = activePlatform.InverseTransformPoint (transform.position); 
// 
//        // If you want to support moving platform rotation as well: 
//        activeGlobalPlatformRotation = transform.rotation; 
//        activeLocalPlatformRotation = Quaternion.Inverse(activePlatform.rotation) * transform.rotation; 
//    } 
   } 

   private void OnControllerColliderHit  (ControllerColliderHit hit) 
   { 

      // Make sure we are really standing on a straight platform 
      // Not on the underside of one and not falling down from it either! 
      if (hit.moveDirection.y < -0.9 && hit.normal.y > 0.5) { 
         //activePlatform = hit.collider.transform; 
         //Debug.Log("I'm on a platform look at me");    
      } 

      Camera mainCamera = FindCamera(); 
      RaycastHit rahit;// = new RaycastHit(); 
      Vector3 Middle = new Vector3(0.5f,0.5f,0f);    
      Ray ray = mainCamera.ViewportPointToRay(Middle); 

      if (0.5 < hit.normal.y && hit.normal.magnitude < 1.01) 
      { 
         //it's a floor or a roof 
         return; 
      } 

      wallsound = SwitchWall(hit.collider); 
      if (wallsound == null) 
      { 
         return; 
      } 

      if (!Physics.Raycast(ray, out rahit, 2) && hasYelled) 
      { 
         //Debug.Log("I don't touch a thing"); 
         wallsound.setWall(0); 
         return; 
      } 
      //Debug.Log("Normal + Direction =" + 1/(hit.normal + me.velocity).magnitude); 
      float newWallvalue = (1/(hit.normal + me.velocity).magnitude); 
      if (hasYelled || me.velocity.magnitude < 2) 
      { 
         //Debug.Log("Was yelling before, reducign number"); 
         newWallvalue *= 0.8f; 

      } 
      //Debug.Log(newWallvalue); 
      //Debug.Log("hit a wall"); 
      if(me.velocity.magnitude < 0.2) 
      { 
         newWallvalue = 0; 
      } 

      wallsound.setPos(hit.point, Vector3.zero);       
      wallsound.setWall(newWallvalue); 

      if (newWallvalue > 0.8) 
      { 
         hasYelled = true; 
         //Debug.Log("I yelled"); 
      } 

      wastouchingwall = true; 

      //Debug.Log("Hit Normal = " + hit.normal.ToString());       
   } 

   private void OnTriggerEnter(Collider other) 
   { 
      if (other.GetComponent<FootstepsSound>() != null) 
      { 
         //Debug.Log("The thing has a footsteps connected"); 
         footsteps = SwitchSteps(other); 
      } 
   } 
   private void OnTriggerStay(Collider other) 
   { 
      inTrigger = true; 
      if (other.GetComponent<FootstepsSound>() != null) 
      { 
         if (footsteps != other.GetComponent<FootstepsSound>()) 
         { 
            //Debug.Log("The thing has a footsteps connected"); 
            footsteps = SwitchSteps(other); 
         } 
      } 
   } 
   private void OnTriggerExit(Collider other) 
   { 
      inTrigger = false; 
   } 

   private FootstepsSound SwitchSteps(Collider hitthing) 
   { 
      FootstepsSound newfootsteps; 
      newfootsteps = hitthing.GetComponent<FootstepsSound>(); 
      float curspeed = footsteps.getSpeed(); 
      footsteps.End(); 
      footsteps.setSpeed(0); 
      newfootsteps.setSpeed(curspeed);       
      newfootsteps.Begin(); 
      return newfootsteps; 
   } 

   private WallPatSound SwitchWall(Collider hitthing) 
   { 
      WallPatSound newWall = null; 
      if(hitthing.GetComponent<WallPatSound>() != null) 
      { 
         newWall = hitthing.GetComponent<WallPatSound>(); 
      } 
      else if(GetComponent<WallPatSound>() != null) 
      { 
         newWall = GetComponent<WallPatSound>(); 
      } 
      if (newWall == null) 
      { 
         Debug.LogWarning("There is no wall-pat sound available here"); 
         return newWall; 
      } 
      if (newWall != wallsound) 
      { 
         Debug.Log("Changing Wallpat Sound"); 
         float curwall = wallsound.getWall(); 
         wallsound.setWall(0); 
         wallsound.End(); 
         newWall.setWall(curwall); 
         newWall.Begin(); 
      } 
      return newWall; 
   } 

   private static void checkTurning(float oldRotation) 
   { 

   } 

   private static void ERRCHECK(FMOD.RESULT result) 
    { 
        if (result != FMOD.RESULT.OK) 
        { 
            Debug.Log("FMOD error! " + result + " - " + FMOD.Error.String(result)); 
        } 
    } 

   private FMOD.VECTOR VectorConvert (Vector3 Vector) 
    { 
       FMOD.VECTOR end; 
       end.x = Vector.x; 
       end.y = Vector.y; 
       end.z = Vector.z; 
       return end; 
    } 

    private Camera FindCamera () 
   { 
      if (camera) 
      { 
         return camera; 
      } 
      else 
      { 
         return Camera.main; 
      } 
   } 
} 

Thanks!!! (and sorry about the really really long post / script with lots commented out... :S)

You're reinventing the wheel. Unity already does exactly what you're trying to do, and it does it all for you.

Please read this page very carefully:

http://unity3d.com/support/documentation/Manual/Sound.html

Unity already contains an Audio Listener component that is typically attached to a camera (but it doesn't have to be, necessarily), and "receives" audio from the surrounding game world in 3D, applying rolloff factors, volume, and other effects. Unity 3 will also come with additional effects like reverb, echo, filtering, and custom rolloff curves.

There is absolutely no need for you to tap into the FMOD subsystem in order to achieve what you want, and these scripts are probably mostly useless to you.