Scene Audio Debugger
Seeing every playing FMOD event in the Unity Scene view
Technical Audio · Unity and FMOD tooling · Whitepaper · By Victor Hime · 16 min read
When a sound is missing, doubled or coming from the wrong place, the first question is spatial: where is it playing, and what started it? A middleware profiler shows which events are running. The Unity Scene view shows the level. Neither shows both at once.
The Scene Audio Debugger is a Unity editor tool built by Flutu for that question. In Play Mode it reads every playing event instance from the FMOD Studio system and draws it in the Scene view, with its position, distance range, output level, state and, when it can be identified, the GameObject that started it.
This paper explains how the tool collects its data, how to read its markers, what it cannot see and how another team could build a similar view. The behavior described was read from the tool's source as of October 29, 2026; no measured results are reported.
TL;DR
-
01
The tool asks FMOD for its playing instances instead of scanning scene components, so sounds started from code, animation events or pooled managers appear next to sounds started by emitters.
-
02
3D events are drawn where FMOD places them, with discs for minimum and maximum distance. 2D events are drawn at the GameObject that triggered them, when that object is known, with a dotted line to the listener.
-
03
Each marker carries the event name, its output level in dB, its distance to the listener and flags for virtual, paused and stopping instances.
-
04
An overlay panel lists 2D events that have no place in the world, such as music and ambience beds, and shows the parameters of the selected instance.
-
05
The tool runs only in the Unity Editor and only in Play Mode. It samples the current state; it does not record a history.
Where is that sound coming from?
Consider three illustrative bug reports: “The waterfall is silent from the bridge.” “There are two rivers playing in this valley.” “The menu music is still on in the forest.” Each one is about a place, so someone has to connect what the audio system is doing with where things are in the level.
The usual tools each answer half. The FMOD Studio profiler shows which events started, when and how loud, but not the level around them. The Scene view shows geometry, but an emitter only says an event is assigned: not whether an instance is playing, where FMOD places it or whether code started a second one.
Log lines and per-component gizmos cover one call path at a time and miss sounds started from code, animation events or pooled managers. Without a combined view, triage slows down for sound designers, audio programmers, QA and external audio teams: is the problem in the event, the placement or the trigger? Each answer has a different owner.
Ask the audio system, not the components
The central design decision is to read playing instances from the middleware itself. A component scan can only find sounds that live on components. The FMOD Studio system knows about every instance of every event in its loaded banks, however it was created.
The tool takes three kinds of input:
- The FMOD Studio system: loaded banks, their event descriptions, each description's live instances and, for each instance, its playback state, position, distance range, virtual and paused flags, parameters and output metering.
- The FMOD listener: position and facing of the first listener.
- Unity-side ownership lookups: emitter components in the open scenes and the lists in which the FMOD for Unity runtime and the project's sound manager keep the objects they attached instances to.
It produces two outputs: markers drawn in the Scene view and an overlay panel with filters, the selected instance and lists of what is playing.
The tool does not start, stop or modify sounds. Its only write to the audio system is turning on output metering for the instances it reads, so that it can display their level.
Some responsibilities stay with the team using it. Event categories are derived from the project's event folder names, so the rule has to match the project's conventions. The ownership lookups depend on how the project's own sound manager stores instances, so they need adapting per project. And the tool shows behavior; it does not decide whether that behavior is a bug.
Scene Audio Debugger: reading live FMOD state
What the tool reads, and how often
The tool polls the FMOD Studio API from the editor update loop. Different data refreshes at different rates: the event catalog changes rarely, while instances change every frame.
| Data | Read from | Refresh interval |
|---|---|---|
| Event catalog: path and 3D flag | Studio system bank list, then each bank's event list | 2 s |
| Emitter components in the scene | Unity search for active emitter components: the FMOD for Unity emitter and the project's own emitter base class | 1 s |
| Instance ownership | Emitter components, the FMOD for Unity runtime's attached-instance list and the project sound manager's instance pool | 50 ms |
| Playing instances | Each event description's instance count and instance list; stopped instances are skipped | 50 ms |
| Playback state | Instance playback state, paused flag and virtual flag | 50 ms |
| Position | Instance 3D attributes, for 3D events only | 50 ms |
| Distance range | Instance minimum and maximum distance | 50 ms |
| Output level | RMS from output metering on the head DSP of the instance's channel group, combined across channels | 50 ms |
| Listener | Position and forward vector of listener 0 | 50 ms |
| Parameters | Selected instance only: local parameters from the instance, global parameters from the Studio system | Each overlay repaint |
Three consequences follow from this design.
A newly started instance reads minus infinity for one refresh, because metering is switched on the first time the tool reads it.
Events in a bank loaded during the session appear within one catalog refresh, up to two seconds later.
The level is measured on the event's own output. It includes the event's volume and spatializer and excludes the buses, VCAs and snapshots downstream. A marker can show a healthy level for an event that is attenuated or muted further down the mix.
Instances are listed in descending order of measured level.
Reading the Scene view
Each playing instance with a known place gets a marker. 3D events are placed where FMOD says they are, which is not necessarily where their GameObject is. 2D events have no position in FMOD, since they play at the listener, so the tool draws them where they were triggered from.
| Marker | Meaning | Where it is drawn |
|---|---|---|
| Sphere | A 3D event instance | FMOD's 3D position for that instance |
| Filled disc with outline | Minimum distance of a 3D instance | Horizontal plane at the instance's height |
| Outer outline disc | Maximum distance of a 3D instance; thicker when selected | Horizontal plane at the instance's height |
| Square | A 2D event instance with a known source | Position of the source GameObject |
| Dotted line | A 2D instance plays at the listener, not at its source | From the source GameObject to the listener |
| Solid line | Link between a 3D instance and the listener | Drawn for the selected instance, or for every audible 3D instance when the option is on |
| Circle with arrow | The FMOD listener, its position and facing | Listener position |
| Grey tint | The instance is virtual, paused or below -60 dB | Applied to any marker |
Color identifies the category, derived from the event's folder path. Any event outside the configured folders falls into the default category.
| Category | Marker color | Assigned when |
|---|---|---|
| SFX | Orange | Default for events that match no other rule |
| Ambience | Green | Event path is in the ambience folders |
| Music | Pink | Event path is in the music folder |
| VO | Cyan | Event path is in the voice folder |
| UI | Light grey | Event path is in the UI folder |
Labels show the event name and a status line. For a 3D instance the line reads, as an illustrative example, 3D -18 dB 12/40 m: level, current distance to the listener and maximum distance. For a 2D instance it reads 2D -12 dB from followed by the source object's name. The words virtual, paused or stopping are appended when they apply. To keep the view readable, labels appear only within 80 m of the Scene view camera; the selected instance is always labeled.
Markers are drawn with Unity editor handles rather than gizmos. They stay visible when the Scene view's Gizmos button is off, which lets the user hide colliders, camera frustums and icons while keeping the audio layer.
Clicking a marker selects that instance and, when its source is known, selects and highlights the source GameObject in the hierarchy.
Tracing playback and ownership
The overlay panel
A panel docked in the Scene view, titled “Flutu Audio”, controls the debugger. Enabling the debugger from the editor menu opens this panel in every Scene view.
| Control | Effect |
|---|---|
| Audio debugger | Turns the debugger on or off. |
| Gizmos · Grid | Shortcuts to the Scene view toggles. Audio markers remain visible with Gizmos off. |
| 3D · 2D | Show or hide 3D and 2D instances. |
| Virtual | Show or hide virtual instances. |
| Labels | Show or hide marker labels. The selected instance keeps its label. |
| Min/max | Show or hide distance discs. The selected instance keeps its discs. |
| Lines to listener | Draw a line from every audible 3D instance to the listener. |
| Name filter | Show only instances whose event path contains the text, ignoring case. |
| Max dist (m) | Show only instances within this distance of the listener, from 0 to 300 m. 0 means no limit. Instances without a place are not affected. |
When an instance is selected, the panel shows its name and full event path; for a 3D event its minimum, maximum and current listener distance, or for a 2D event the note that it plays at the listener; its playback state, level and flags; a read-only reference to its source object; and the current value of every parameter, with global parameters marked as such.
Below, a summary line counts playing instances, 3D instances shown, 2D instances without a place and virtual instances. The list starts with 2D instances without a place, such as music, ambience beds and UI, which have no marker in the scene. Instances with a place sit in a collapsible group underneath. Clicking a row selects the instance and frames the Scene view on it, at a distance based on its maximum distance.
Toggle and filter settings are stored per machine in editor preferences. Instance data and selection are cleared when Play Mode ends.
Who started it
FMOD knows an instance's position but not which GameObject created it. The tool builds that link from four lookups, refreshed every 50 ms.
| Lookup | Finds instances started by | Access |
|---|---|---|
| Project emitter components | The project's own emitter components in the open scenes | Public instance reference on the component |
| FMOD for Unity emitters | Studio Event Emitter components in the open scenes | Public instance reference on the component |
| Runtime attached instances | Code that attached an instance to a GameObject through the FMOD for Unity runtime manager | Private list, read by reflection |
| Project sound manager pool | The project's central playback API, which keeps pooled instances with a target transform | Private pool, read by reflection |
An instance found by none of these lookups has no source. A 3D instance without a source is still drawn at FMOD's position, but selecting it cannot select a GameObject. A 2D instance without a source has no place to be drawn, so it appears only in the overlay list.
The two reflection lookups depend on private fields. If an FMOD for Unity update or a change to the project's sound manager alters those fields, the tool catches the error and stops showing sources, without a warning. This was a deliberate choice for a debugging view that must never interrupt Play Mode. It also means that a missing source can indicate a broken lookup rather than an unusual call path.
Seeing what the player sees
A companion editor tool, Sync Scene View to Game Camera, copies the game camera's position, rotation, field of view and clip planes to the last active Scene view every frame during Play Mode. With both tools on, the Scene view shows the player's framing with the audio markers on top, which makes it easier to compare an emitter's position and the listener's facing with what is on screen.
The Scene view's own camera settings are saved when the sync starts and restored when it stops or when Play Mode ends.
What the evidence establishes
The material behind this paper is the tool's source code. It contains no retained screenshots, session notes, bug records or timing measurements. The three statements below separate what can be supported from what cannot yet.
-
Implemented and source-reviewed
The data collection, markers, overlay, ownership lookups and companion camera sync described in this paper were read from the source.
-
Observed in use
The tool was built for, and used in, a live production. No specific debugging cases are documented here.
-
Not measured
Time saved during debugging, number of issues found with the tool and the tool's own editor overhead.
| Claim | Supporting material | What it establishes | Limit |
|---|---|---|---|
| The tool sees instances regardless of how they were started. | Source: instances are enumerated from every event description in the loaded banks. | Any instance alive in a loaded bank at sampling time is reachable. | Sampling every 50 ms can miss very short one-shots. Banks loaded during the session appear after up to 2 s. |
| 3D markers show FMOD's position, not the GameObject's. | Source: position comes from each instance's 3D attributes. | A mismatch between an instance and its object becomes visible in the scene. | No retained example of such a mismatch found with the tool. |
| The level shows each instance's contribution. | Source: RMS output metering on the event's head DSP. | Relative loudness of instances before the mix. | Not the final output level; not calibrated loudness; reads minus infinity on the first refresh. |
| The tool can name the object that started a sound. | Source: four ownership lookups. | Emitters, runtime-attached instances and the project's pooled instances can be attributed. | Two lookups use private fields and fail silently. Other call paths have no source. |
| The tool has no effect on builds. | Source: all files are in an editor-only folder, which Unity excludes from player builds. | No runtime code or data ships with the game. | It cannot be used to debug device or console builds. |
| The view speeds up audio debugging. | The author's assessment. | The tool is considered useful by the team that built it. | No timing comparison or case record supports a quantified gain. |
Where the view stops being useful
Editor and Play Mode only
The tool lives in the Unity Editor. It cannot inspect a build running on a device or console, where the FMOD Studio live profiler remains the tool to use.
A snapshot, not a recording
The tool shows the current state, refreshed about 20 times per second. It keeps no history, and a one-shot that starts and ends between two refreshes may never appear. For questions about timing, such as an ambience restarting during a scene change, a recorded profiler session is the right evidence.
One listener
Only the first FMOD listener is read. Projects with split-screen or several listeners would need to extend the tool.
Range is a simplification
Minimum and maximum distance are drawn as horizontal discs at the instance's height. Vertical distance and the shape of the attenuation curve between the two values are not represented.
Level before the mix
The metered level excludes buses, VCAs and snapshots. An instance can look loud on its marker and still be inaudible in the final mix.
Categories follow naming
Colors depend on event folder names. Events outside the configured folders are shown as SFX, so a project with different conventions needs its own rule.
Ownership needs adapting
Two of the four ownership lookups read private fields of FMOD for Unity and of one project's sound manager. They break silently when either changes, and another project needs its own equivalent.
Editor overhead
Every 50 ms the tool walks every event description in the loaded banks, and it enables metering on each instance it reads until that instance is released. This cost has not been measured. Turning the debugger off before profiling editor performance is a reasonable precaution.
It shows, a person decides
A marker can show a loop playing at the edge of its range or a 2D sound triggered far from the listener. Whether that is a bug, a mix decision or intended behavior is a call for the audio team, not the tool.
Building a similar view for your project
- 01
Read instances from the middleware.
In the FMOD Studio API, the path is bank list, event descriptions per bank, then instance list per description. If you use other middleware, check first whether it exposes active instances, their positions and their metering to the editor.
- 02
Separate refresh rates.
Refresh the event catalog slowly and the instance state quickly. Keep the instance pass light, since it runs many times per second.
- 03
Draw positions from the audio system.
Use the instance's own 3D attributes, not its GameObject's transform, so placement mismatches stay visible.
- 04
Give 2D events a place.
Draw them at the object that triggered them, when known, and list the rest in a panel so music and beds are not forgotten.
- 05
Define a category rule from your event naming.
Decide what the default category is and check that it does not hide events that should stand out.
- 06
Map every call path in your project to an ownership lookup.
Include emitters, runtime attachment and any central sound manager. Consider showing an explicit warning when a lookup fails; the tool described here fails silently.
- 07
Keep the tool editor-only.
Nothing ships with the game.
- 08
Pair it with recorded profiler sessions for timing questions.
The live view helps decide where to look; the recording documents what happened.
Before relying on such a view, check it against a small test scene with known cases:
| Test case | Expected result |
|---|---|
| A 3D loop on a placed object | Sphere at the object's position, with minimum and maximum distance discs |
| A 3D instance whose position differs from its object | Sphere at FMOD's position, not at the object |
| A 2D one-shot started from gameplay code | Square at the triggering object, dotted line to the listener, or a list entry if no source is known |
| A 3D loop outside its maximum distance | Grey marker, flagged as virtual if FMOD virtualized it |
| A paused instance | Grey marker, flagged as paused |
| An event with a global parameter | Parameter listed with the global mark in the selected-instance panel |
| Music started with no source object | Entry in the list of 2D events without a place |
This checklist is offered for adaptation. It is not a record of tests performed on the tool described here.
Flutu's earlier Labs publication, Before We Touch a Sound, places this kind of view in the observe phase of auditing an inherited audio implementation, next to recorded profiler sessions.
Questions We Can Answer
Why does Flutu publish technical whitepapers?
Around 99% of our projects are covered by strict non-disclosure agreements. That limits how much we can share through named case studies, project footage or internal production material.
Whitepapers give us a way to document how we have helped AA and AAA teams develop working methods, implementation standards and validation workflows, while respecting those confidentiality commitments. We focus on the methods, technical reasoning and evidence we can share without exposing protected project details.
This gives prospective partners a clearer basis for technical evaluation and due diligence: how we investigate systems, structure production work and check results. Each paper distinguishes what was implemented, what was observed and what remains unverified.
How can I see which FMOD events are playing, and where, inside the Unity Scene view?
During Play Mode, read the instance list of every event description in the loaded banks and draw each instance in the Scene view: 3D instances at their FMOD 3D attributes, 2D instances at the object that triggered them when it is known. The Scene Audio Debugger does this from an editor-only script, refreshing instance data every 50 ms.
Why can a sound's FMOD position differ from its GameObject?
FMOD uses the 3D attributes last set on the instance. If the instance is not attached to the moving object, or its attributes are set from another transform, FMOD keeps playing it from a different place. Drawing the FMOD position instead of the transform makes that mismatch visible.
How can I tell which GameObject started a sound during Play Mode?
FMOD does not record which object created an instance. Build a lookup for each call path your project uses: emitter components, instances attached through the FMOD for Unity runtime and any central sound manager pool. Instances outside those paths will have no source, and that absence should be treated as a lead rather than an answer.
What does a live audio view miss that a recorded profiler session captures?
History. A view refreshed about 20 times per second shows the current state only. Short one-shots between refreshes can be missed, and nothing is kept once the moment passes. Questions about order and timing, such as a loop restarting during a scene change, need a recorded profiler session.
Flutu's technical audio team builds debugging and implementation tools inside a game's existing pipeline, alongside audits, middleware integration and production support.