<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Audio Implementation on DAD 424 Sound Design for Games</title><link>https://dsu-digital-sound-design.github.io/f-25-dad-424-sound-design-for-games/tags/audio-implementation/</link><description>Recent content in Audio Implementation on DAD 424 Sound Design for Games</description><generator>Hugo -- gohugo.io</generator><language>en</language><lastBuildDate>Wed, 12 Jun 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://dsu-digital-sound-design.github.io/f-25-dad-424-sound-design-for-games/tags/audio-implementation/index.xml" rel="self" type="application/rss+xml"/><item><title>FMOD Namespaces</title><link>https://dsu-digital-sound-design.github.io/f-25-dad-424-sound-design-for-games/lectures/week-11/fmod-namespaces/</link><pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate><guid>https://dsu-digital-sound-design.github.io/f-25-dad-424-sound-design-for-games/lectures/week-11/fmod-namespaces/</guid><description>Key Concepts Namespaces group related types in C# and avoid name collisions. Using directives (using ...;) make types in a namespace available without full qualification. Unity and FMOD both expose APIs through namespaces that you reference from your scripts. Recap: Namespaces &amp;amp; Classes in Unity When you create a new Unity script, you’ll see using directives at the top—these specify namespaces. They let you access types from Unity’s API without fully qualifying them.</description><content>&lt;h2 id="key-concepts">&lt;strong>Key Concepts&lt;/strong>&lt;/h2>
&lt;ul>
&lt;li>Namespaces group related types in C# and avoid name collisions.&lt;/li>
&lt;li>Using directives (&lt;code>using ...;&lt;/code>) make types in a namespace available without full qualification.&lt;/li>
&lt;li>Unity and FMOD both expose APIs through namespaces that you reference from your scripts.&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Recap: Namespaces &amp;amp; Classes in Unity&lt;/strong>
When you create a new Unity script, you’ll see using directives at the top—these specify namespaces. They let you access types from Unity’s API without fully qualifying them. Below that, each script defines a public class that usually inherits from &lt;code>MonoBehaviour&lt;/code>, which provides lifecycle methods like &lt;code>Start()&lt;/code> and &lt;code>Update()&lt;/code>. &lt;code>MonoBehaviour&lt;/code> lives in the &lt;code>UnityEngine&lt;/code> namespace.&lt;/p>
&lt;p>You can view the definition of classes like &lt;code>MonoBehaviour&lt;/code> in Visual Studio using “Go To Definition,” which helps to reveal their structure and included namespaces.&lt;/p>
&lt;p>Block-scoped and file-scoped namespaces:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Block-scoped (common in Unity projects)&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">namespace&lt;/span> UnityEngine
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">MonoBehaviour&lt;/span> : Behaviour
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// class contents&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>File-scoped (C# 10+):&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">namespace&lt;/span> UnityEngine;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">MonoBehaviour&lt;/span> : Behaviour
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// class contents&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="working-with-namespaces">&lt;strong>Working with Namespaces&lt;/strong>&lt;/h2>
&lt;p>Create a new script in Unity called &lt;code>MyScript.cs&lt;/code> to explore namespaces.&lt;/p>
&lt;p>If you remove a using directive (for example, &lt;code>using UnityEngine;&lt;/code>), references like &lt;code>MonoBehaviour&lt;/code> will no longer resolve and you’ll get compiler errors. You can also declare your own namespaces to organize custom scripts.&lt;/p>
&lt;p>For example, using a traditional namespace declaration:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">namespace&lt;/span> MyNamespace {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">MyClass&lt;/span> { }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>To use &lt;code>MyClass&lt;/code>, either add &lt;code>using MyNamespace;&lt;/code> to the top of another script or fully qualify it as &lt;code>MyNamespace.MyClass&lt;/code>.&lt;/p>
&lt;p>&lt;code>MonoBehaviour&lt;/code> derives from the &lt;code>Behaviour&lt;/code> class (also in &lt;code>UnityEngine&lt;/code>). Use “Go To Definition” in your IDE to trace the inheritance chain and see which namespaces types come from.&lt;/p>
&lt;h2 id="fmod-namespaces-in-unity">&lt;strong>FMOD Namespaces in Unity&lt;/strong>&lt;/h2>
&lt;p>FMOD commands for game audio, like &lt;code>PlayOneShot&lt;/code>, rely on namespaces just like Unity does. Example component:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> FMODUnity;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> UnityEngine;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">PlayEvent&lt;/span> : MonoBehaviour
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e"> [SerializeField]&lt;/span> &lt;span style="color:#66d9ef">private&lt;/span> &lt;span style="color:#66d9ef">string&lt;/span> eventPath; &lt;span style="color:#75715e">// or use EventReference&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> Start()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Positional one-shot&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> RuntimeManager.PlayOneShot(eventPath, transform.position);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Or, to attach to a GameObject:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// RuntimeManager.PlayOneShotAttached(eventPath, gameObject);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Here:&lt;/p>
&lt;ul>
&lt;li>&lt;code>FMODUnity&lt;/code> is the FMOD Unity integration namespace.&lt;/li>
&lt;li>&lt;code>RuntimeManager&lt;/code> is a class within &lt;code>FMODUnity&lt;/code>.&lt;/li>
&lt;li>&lt;code>PlayOneShot&lt;/code>/&lt;code>PlayOneShotAttached&lt;/code> are methods on &lt;code>RuntimeManager&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>To see how these work, open the FMOD integration scripts in your project (for example, &lt;code>RuntimeManager.cs&lt;/code>) and inspect how namespaces and classes are organized. Declaring &lt;code>using FMODUnity;&lt;/code> lets you call &lt;code>RuntimeManager.PlayOneShot(...)&lt;/code> without repeatedly writing the full namespace.&lt;/p>
&lt;p>Go and find your Unity project’s &lt;code>FMODUnity&lt;/code> folder (usually under &lt;code>Assets/Plugins/FMOD/src&lt;/code>) to explore the FMOD classes and their namespaces.&lt;/p>
&lt;h3 id="understanding-playoneshot">Understanding PlayOneShot&lt;/h3>
&lt;p>Common overloads you’ll use in Unity:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Positional one‑shot at a world position&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RuntimeManager.PlayOneShot(&lt;span style="color:#66d9ef">string&lt;/span> eventPath, Vector3 position);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RuntimeManager.PlayOneShot(EventReference eventRef, Vector3 position);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// One‑shot attached to and following a GameObject&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RuntimeManager.PlayOneShotAttached(&lt;span style="color:#66d9ef">string&lt;/span> eventPath, GameObject go);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>RuntimeManager.PlayOneShotAttached(EventReference eventRef, GameObject go);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Notes:&lt;/p>
&lt;ul>
&lt;li>Fire‑and‑forget: these methods return &lt;code>void&lt;/code>. You can’t stop or change parameters afterwards. For control, use &lt;code>FMOD.Studio.EventInstance&lt;/code> or a &lt;code>StudioEventEmitter&lt;/code>.&lt;/li>
&lt;li>Position vs attached: &lt;code>PlayOneShot&lt;/code> uses a fixed &lt;code>Vector3&lt;/code> at spawn time; &lt;code>PlayOneShotAttached&lt;/code> follows the GameObject’s transform.&lt;/li>
&lt;li>EventReference vs string: &lt;code>EventReference&lt;/code> is type‑safe and assignable in the Inspector; a string path is quick but error‑prone.&lt;/li>
&lt;/ul>
&lt;p>Example using an &lt;code>EventReference&lt;/code> field:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> FMODUnity;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> UnityEngine;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">PlayEventRef&lt;/span> : MonoBehaviour
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#a6e22e"> [SerializeField]&lt;/span> &lt;span style="color:#66d9ef">private&lt;/span> EventReference eventRef;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> Start()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> RuntimeManager.PlayOneShot(eventRef, transform.position);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Or follow this GameObject:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// RuntimeManager.PlayOneShotAttached(eventRef, gameObject);&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="example-when-you-need-control">Example: When You Need Control&lt;/h2>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// For parameter control, don&amp;#39;t use PlayOneShot:&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">var&lt;/span> instance = RuntimeManager.CreateInstance(&lt;span style="color:#e6db74">&amp;#34;event:/Music/Stinger&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>instance.setParameterByName(&lt;span style="color:#e6db74">&amp;#34;Intensity&amp;#34;&lt;/span>, &lt;span style="color:#ae81ff">0.8f&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>instance.start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// ... later, you can modify or stop it ...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>instance.release();
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;h2 id="key-takeaway">Key Takeaway&lt;/h2>
&lt;p>&lt;strong>The GUID overload is the &amp;ldquo;real&amp;rdquo; function&lt;/strong> - the EventReference and string versions are just convenient wrappers that convert their input to GUID and pass it along. This is a common design pattern called the &lt;strong>Telescoping Pattern&lt;/strong> or &lt;strong>Overload Chaining&lt;/strong>.&lt;/p>
&lt;p>&lt;strong>Bottom line:&lt;/strong> PlayOneShot functions are perfect for simple one-off sounds that don&amp;rsquo;t need runtime control.&lt;/p>
&lt;h3 id="event-instances-and-nested-namespaces">&lt;strong>Event Instances and Nested Namespaces&lt;/strong>&lt;/h3>
&lt;p>FMOD exposes nested namespaces, such as &lt;code>FMOD.Studio.EventInstance&lt;/code>:&lt;/p>
&lt;ul>
&lt;li>&lt;code>FMOD&lt;/code> is a namespace.&lt;/li>
&lt;li>&lt;code>Studio&lt;/code> is a nested namespace inside &lt;code>FMOD&lt;/code>.&lt;/li>
&lt;li>&lt;code>EventInstance&lt;/code> is a struct inside &lt;code>Studio&lt;/code>.&lt;/li>
&lt;/ul>
&lt;p>Open up the definition of &lt;code>EventInstance&lt;/code> in Visual Studio to see its members and methods. &lt;code>EventInstance&lt;/code> is a value type (struct) representing a playable instance of an FMOD event.&lt;/p>
&lt;blockquote>
&lt;p>Struct: A value type that holds data directly, unlike classes which are reference types.&lt;/p>
&lt;/blockquote>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">struct&lt;/span> &lt;span style="color:#a6e22e">EventInstance&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Methods and properties for controlling the event instance&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> RESULT start();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> RESULT stop(STOP_MODE mode);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">public&lt;/span> RESULT setParameterByName(&lt;span style="color:#66d9ef">string&lt;/span> name, &lt;span style="color:#66d9ef">float&lt;/span> &lt;span style="color:#66d9ef">value&lt;/span>);
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// ... more members ...&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>See if you can find methods like &lt;code>start()&lt;/code>, &lt;code>stop()&lt;/code>, and &lt;code>setParameterByName()&lt;/code> in the definition.&lt;/p>
&lt;p>If you use types from &lt;code>FMOD.Studio&lt;/code>, add the appropriate using directives:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> FMOD;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">using&lt;/span> FMOD.Studio;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Alternatively, fully qualify names (for example, &lt;code>FMOD.Studio.EventInstance&lt;/code>).&lt;/p>
&lt;p>&lt;strong>Streamlining Your Scripts&lt;/strong>
Unity sometimes adds unused namespaces to your scripts by default. Visual Studio will gray out those not needed; clean them up to keep your code clear.&lt;/p>
&lt;p>&lt;strong>Wrap-Up&lt;/strong>
By understanding and leveraging namespaces you can:&lt;/p>
&lt;ul>
&lt;li>Organize code clearly and avoid name collisions.&lt;/li>
&lt;li>Use shorter, clearer code with &lt;code>using&lt;/code> directives or fully qualified names when appropriate.&lt;/li>
&lt;li>Navigate Unity and FMOD APIs more confidently during audio implementation.&lt;/li>
&lt;/ul></content></item><item><title>Interpreting Code: Understanding Game Scripts as an Audio Designer</title><link>https://dsu-digital-sound-design.github.io/f-25-dad-424-sound-design-for-games/lectures/week-11/interpreting-code/</link><pubDate>Wed, 12 Jun 2024 00:00:00 +0000</pubDate><guid>https://dsu-digital-sound-design.github.io/f-25-dad-424-sound-design-for-games/lectures/week-11/interpreting-code/</guid><description>Interpreting Code: Understanding Game Scripts as an Audio Designer When designing sound for games, we often spend our time inside FMOD, Wwise, or Unity’s audio windows—triggering events, mixing layers, and crafting dynamic soundscapes. But at some point, we hit a barrier: to make our sounds respond to gameplay, we need to understand the game’s code.
This post walks you through the fundamentals of reading and using existing scripts—without needing to become a full-on programmer.</description><content>&lt;h1 id="interpreting-code-understanding-game-scripts-as-an-audio-designer">Interpreting Code: Understanding Game Scripts as an Audio Designer&lt;/h1>
&lt;p>When designing sound for games, we often spend our time inside FMOD, Wwise, or Unity’s audio windows—triggering events, mixing layers, and crafting dynamic soundscapes. But at some point, we hit a barrier: to make our sounds respond to gameplay, we need to understand &lt;em>the game’s code.&lt;/em>&lt;/p>
&lt;p>This post walks you through the fundamentals of reading and using existing scripts—without needing to become a full-on programmer. It’s about collaboration, curiosity, and creative problem-solving through code.&lt;/p>
&lt;hr>
&lt;h2 id="general-vs-custom-audio-implementation">General vs. Custom Audio Implementation&lt;/h2>
&lt;p>Audio in games generally falls into two categories:&lt;/p>
&lt;h3 id="general-implementation">General Implementation&lt;/h3>
&lt;p>These sounds use built-in tools from Unity or FMOD. You don’t need to touch other scripts to make them work.
Examples include ambient loops, trigger-based footsteps, or teleport sounds using Unity’s collider system.&lt;/p>
&lt;h3 id="custom-implementation">Custom Implementation&lt;/h3>
&lt;p>These sounds rely on &lt;em>code written by developers&lt;/em>. They interact with the game’s systems—like dynamic music that changes when the player enters combat or a car engine pitch that follows RPM.&lt;/p>
&lt;table>
&lt;thead>
&lt;tr>
&lt;th>Aspect&lt;/th>
&lt;th>General Implementation&lt;/th>
&lt;th>Custom Implementation&lt;/th>
&lt;/tr>
&lt;/thead>
&lt;tbody>
&lt;tr>
&lt;td>What it is&lt;/td>
&lt;td>Uses built-in tools in Unity or FMOD; no script edits needed&lt;/td>
&lt;td>Relies on developer-written code; hooks into gameplay systems&lt;/td>
&lt;/tr>
&lt;tr>
&lt;td>Examples&lt;/td>
&lt;td>Ambient loops; trigger-based footsteps; teleport sounds via colliders&lt;/td>
&lt;td>Dynamic music reacting to combat; engine pitch following RPM&lt;/td>
&lt;/tr>
&lt;/tbody>
&lt;/table>
&lt;p>To handle these, you’ll need to identify where the relevant variables and functions live in code.&lt;/p>
&lt;hr>
&lt;h2 id="reading-game-code-without-fear">Reading Game Code Without Fear&lt;/h2>
&lt;p>Let’s use Unity’s &lt;strong>PlayerController&lt;/strong> script (from the 3D Game Kit) as an example. Even without programming experience, you can learn a lot by exploring the script methodically.&lt;/p>
&lt;h3 id="1-look-at-variable-names">1. Look at Variable Names&lt;/h3>
&lt;p>Names like &lt;code>JumpSpeed&lt;/code>, &lt;code>Gravity&lt;/code>, or &lt;code>m_ReadyToJump&lt;/code> tell you their purpose.
If a variable is &lt;em>public&lt;/em>, you’ll also see it in Unity’s Inspector—meaning you or another script can adjust it at runtime.&lt;/p>
&lt;p>In another script attached to Ellen you could have:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">public&lt;/span> &lt;span style="color:#66d9ef">class&lt;/span> &lt;span style="color:#a6e22e">EllenAudio&lt;/span> : MonoBehaviour
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Reference to the PlayerController script&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">private&lt;/span> PlayerController pc;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#66d9ef">void&lt;/span> Start() {
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Get the PlayerController component&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pc = GetComponent&amp;lt;PlayerController&amp;gt;();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> pc.JumpSpeed = &lt;span style="color:#ae81ff">10.0f&lt;/span>; &lt;span style="color:#75715e">// Example of accessing JumpSpeed variable&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> }
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>You might also spot variables like:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">bool&lt;/span> m_IsGrounded;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">bool&lt;/span> m_PreviouslyGrounded;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>These booleans (true/false variables) control jumping logic. Understanding their behavior helps us know when to trigger audio—like footsteps, landings, or jump sounds.&lt;/p>
&lt;hr>
&lt;h3 id="2-read-the-programmer-notes">2. Read the Programmer Notes&lt;/h3>
&lt;p>Most scripts include comments after &lt;code>//&lt;/code>.
These notes explain why a line of code exists. For example:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#75715e">// Whether or not the input state and Ellen are correct to allow jumping&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Comments like this tell you the intent behind a variable—perfect clues when you’re connecting audio to gameplay.&lt;/p>
&lt;hr>
&lt;h3 id="3-trace-variables-in-code">3. Trace Variables in Code&lt;/h3>
&lt;p>In Visual Studio or VS Code, double-click a variable to highlight every place it’s used.
Follow it through the script to see &lt;em>where it changes value&lt;/em>.&lt;/p>
&lt;p>You can also right click and select &amp;ldquo;Find All References&amp;rdquo; to see every instance of that variable in the script.&lt;/p>
&lt;p>For example, you might find:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> FixedUpdate()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> m_PreviouslyGrounded = m_IsGrounded;
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> CalculateVerticalMovement();
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>&lt;code>FixedUpdate()&lt;/code> runs 50 times per second—ideal for physics checks.
Here, the code tracks whether Ellen &lt;em>was&lt;/em> on the ground last frame versus &lt;em>is&lt;/em> on the ground now. That’s exactly the kind of information you could use for sound triggers.&lt;/p>
&lt;hr>
&lt;h2 id="debugging-to-learn">Debugging to Learn&lt;/h2>
&lt;p>Debugging isn’t just for programmers—it’s an &lt;em>auditory designer’s microscope.&lt;/em>
By adding a simple print statement, you can &lt;em>watch&lt;/em> how the game behaves in real-time.&lt;/p>
&lt;p>Add this line to your script:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>Debug.Log(&lt;span style="color:#e6db74">&amp;#34;IG: &amp;#34;&lt;/span> + m_IsGrounded + &lt;span style="color:#e6db74">&amp;#34; PG: &amp;#34;&lt;/span> + m_PreviouslyGrounded);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>When you run the game, Unity’s Console will display the variables each frame.
Jump, and you’ll see them flip from true to false and back again.&lt;/p>
&lt;p>To filter specific moments, use an &lt;code>if&lt;/code> statement:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">if&lt;/span> (m_PreviouslyGrounded != m_IsGrounded)
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> Debug.Log(&lt;span style="color:#e6db74">&amp;#34;Grounded state changed!&amp;#34;&lt;/span>);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>This reports only when the player leaves or touches the ground—an exact moment you might trigger a landing sound or dust effect.&lt;/p>
&lt;p>We could use this information now to play a jump sound when the player leaves the ground and a landing sound when they touch down.&lt;/p>
&lt;hr>
&lt;h2 id="searching-through-scripts">Searching Through Scripts&lt;/h2>
&lt;p>Large scripts can feel overwhelming. Thankfully, you can search them.&lt;/p>
&lt;p>&lt;strong>Ctrl+F (Windows)&lt;/strong> or &lt;strong>Cmd+F (Mac)&lt;/strong> brings up a search bar.
Search for a term like &lt;code>die&lt;/code>, and you might find a function:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>&lt;span style="color:#66d9ef">void&lt;/span> Die()
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>{
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span> &lt;span style="color:#75715e">// Called when the player loses all health&lt;/span>
&lt;/span>&lt;/span>&lt;span style="display:flex;">&lt;span>}
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>Now you’ve found the perfect place to play a “death cry” sound.&lt;/p>
&lt;hr>
&lt;h2 id="a-custom-audio-example">A Custom Audio Example&lt;/h2>
&lt;p>Once you find the &lt;code>Die()&lt;/code> function, adding sound is simple:&lt;/p>
&lt;div class="highlight">&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;">&lt;code class="language-csharp" data-lang="csharp">&lt;span style="display:flex;">&lt;span>FMODUnity.RuntimeManager.PlayOneShotAttached(&lt;span style="color:#e6db74">&amp;#34;event:/Player/Death&amp;#34;&lt;/span>, gameObject);
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/div>&lt;p>That single line links FMOD to Unity, playing your event when the player dies.
You can test it instantly—jump into the water or get hit by an enemy, and your audio should trigger when the character respawns.&lt;/p>
&lt;hr>
&lt;h2 id="knowing-when-to-collaborate">Knowing When to Collaborate&lt;/h2>
&lt;p>Sometimes you’ll find that the data you need—like enemy states or vehicle speed—comes from complex systems spread across many scripts. When that happens, it’s best to collaborate with the programmers. They can create clean hooks for audio events faster than you can reverse-engineer the code.&lt;/p>
&lt;p>However, by understanding the basics, you can communicate clearly:&lt;/p>
&lt;blockquote>
&lt;p>“I noticed there’s a &lt;code>bool inCombat&lt;/code> variable in EnemyAI.cs. Could we use that to switch FMOD music states?”&lt;/p>
&lt;/blockquote>
&lt;p>That kind of precise collaboration makes your work more efficient—and helps the whole team.&lt;/p>
&lt;hr>
&lt;h2 id="practice-explore-the-playercontroller">Practice: Explore the PlayerController&lt;/h2>
&lt;p>Here’s your challenge:&lt;/p>
&lt;ol>
&lt;li>Open the &lt;code>PlayerController&lt;/code> script.&lt;/li>
&lt;li>Find the &lt;code>PlayAudio()&lt;/code> function—used to trigger one-shots for footsteps, jumps, and impacts.&lt;/li>
&lt;li>See what conditions must be true before it runs.&lt;/li>
&lt;li>Use &lt;code>Debug.Log()&lt;/code> to print out those variables to the Console.&lt;/li>
&lt;li>Try connecting one of them to an FMOD event.&lt;/li>
&lt;/ol>
&lt;p>You’ll be surprised how much you already understand—and how quickly “interpreting code” becomes part of your creative toolkit.&lt;/p>
&lt;hr>
&lt;h2 id="closing-thoughts">Closing Thoughts&lt;/h2>
&lt;p>Understanding code isn’t about becoming a programmer.
It’s about reading the systems behind your sounds, identifying where to connect, and knowing when to collaborate.&lt;/p>
&lt;p>By interpreting scripts, you gain control over how your soundscapes react to gameplay—and make your audio as dynamic as the worlds you build.&lt;/p></content></item></channel></rss>