x


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)

more ▼

asked Jun 27 '10 at 10:15 PM

Graeme gravatar image

Graeme
53 9 9 15

You posted a block of code which isn't yours, and you're asking us to make it work for you. If you're not going to try to understand what you are doing, then you should team up with a programmer who can do this stuff for you.

Jun 27 '10 at 11:54 PM _Petroz

You misunderstood his post. He's trying to create 3D audio when Unity already does that, and he didn't ask for someone to write his code, he asked to be shown basic programming concepts (and what he was doing wrong), so that he could attempt to fix them himself, which is a lot more than can be said for some users who post here. -- Please read the question and understand what the poster is asking before jumping to conclusions. :)

Jun 28 '10 at 12:08 AM qJake
(comments are locked)
10|3000 characters needed characters left

1 answer: sort voted first

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.

more ▼

answered Jun 28 '10 at 12:04 AM

qJake gravatar image

qJake
11.6k 43 78 161

Except that I'm a student and Unity 3 isn't out yet. Unity 2.6's Audio engine is so simple and useless it hurts! Thus, I'm using the FMOD designer. Also, what are these "effects" you talk about? Unity 2.61 doesn't have any! No reverb, no filters and the rolloff is really not very good. Plus it just has audio clips playing. No interactive sounds. I don't know if you are aware but game sound has come a lot further than the abilities of Unity 2.61. Do you even know what FMOD does?!?

Jun 28 '10 at 09:26 AM Graeme

Yes, I know exactly what Fmod does. If you want "interactive sounds", you need to script that capability into your game. You can control playback, speed, pitch, etc. And like I said, effects like reverb, echo, filtering, and rolloff curves are coming to Unity 3, which comes out this summer (read: very soon). So if you really need effects, you'll just have to wait until Unity 3, because it's really not worth it to try and write a plugin for something that's going to be released in the near future. You should check the Unity blog; they've released a video detailing the new audio features.

Jun 28 '10 at 08:42 PM qJake
(comments are locked)
10|3000 characters needed characters left
Your answer
toggle preview:

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this question

By Email:

Once you sign in you will be able to subscribe for any updates here

By RSS:

Answers

Answers and Comments

Topics:

x3012
x886
x196
x30
x27
x0

asked: Jun 27 '10 at 10:15 PM

Seen: 1825 times

Last Updated: Jun 28 '10 at 12:08 AM