<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Sara</title>
    <description>The latest articles on DEV Community by Sara (@sarasol).</description>
    <link>https://dev.to/sarasol</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3123130%2Ff93acdf3-cf98-4dfb-ab8c-89e2fa90d1dc.jpg</url>
      <title>DEV Community: Sara</title>
      <link>https://dev.to/sarasol</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sarasol"/>
    <language>en</language>
    <item>
      <title>Animating Pixel Art Fabric with Unity Shader</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Sat, 30 Aug 2025 22:23:55 +0000</pubDate>
      <link>https://dev.to/sarasol/animating-pixel-art-fabric-with-unity-shader-6f1</link>
      <guid>https://dev.to/sarasol/animating-pixel-art-fabric-with-unity-shader-6f1</guid>
      <description>&lt;p&gt;This blog explores how I implemented a simple shader that shows the illusion of a rug affected by the wind.&lt;/p&gt;

&lt;p&gt;Lots of tutorials explaining how to do a waving flag shader but it’s always a 3D approach, so let’s just turn this into something that looks appropriate for a pixel art sprite.&lt;/p&gt;

&lt;p&gt;My goal:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmjxcxhkaj2gie08yk51.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkmjxcxhkaj2gie08yk51.gif" alt=" " width="533" height="400"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Shader Components&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Time Based Wave:&lt;/p&gt;

&lt;p&gt;1st step is our typical time based wave that is going to be applied on the sprite. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Control how fast it animates → Time * WaveSpeed&lt;/li&gt;
&lt;li&gt;Set how many waves appear → UV.x * WaveFrequency&lt;/li&gt;
&lt;li&gt;Use Sine wave to oscillate each pixel up&amp;amp;down&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;(Time * WaveSpeed) + (UV.X * WaveFrequency) → Sine Wave&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Dview%26id%3D1rSvbvRy3Yq_g4546x3Y-x6DYNWLZGI0e" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Dview%26id%3D1rSvbvRy3Yq_g4546x3Y-x6DYNWLZGI0e" alt="TimeBasedWave" width="1813" height="789"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To better understand it, I imagine if we paused time, we get too see each pixel at a different position on the sine curve and if we continue, all pixels shift position simulating the wave effect.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05zupvik9l09pdidyxsv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F05zupvik9l09pdidyxsv.png" alt=" " width="552" height="325"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Secondary Wave for natural variation:&lt;/p&gt;

&lt;p&gt;It is exactly the same as the first wave, except we could change the values of WaveSpeed(1.7) &amp;amp; WaveFrequency(2.2) a bit to add some natural variation to the wave and avoid a repetitive sine wave. Another thing added is the amplitude ratio, in my case (0.6) looked fairly good to avoid overpowering our main time based wave.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Dview%26id%3D1_rfjhvj3-3pvDOVxfTUlF7pU1uoJruF_" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Dview%26id%3D1_rfjhvj3-3pvDOVxfTUlF7pU1uoJruF_" alt="SecondaryWave" width="1418" height="682"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wave Displacement:&lt;/p&gt;

&lt;p&gt;Now we have got two waves and we need to combine them together&lt;/p&gt;

&lt;p&gt;(Wave1+Wave2) * DampeningPower(0.004)&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi29fak4qk4m6d2mpbmpv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi29fak4qk4m6d2mpbmpv.png" alt=" " width="618" height="423"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pixel Snapping:&lt;/p&gt;

&lt;p&gt;This is crucial step for my case since I want to keep the pixelated aesthetic to the sprite, without it the sprite will have very smooth wave effect which I don’t need in my case.&lt;/p&gt;

&lt;p&gt;Floor(Wave Displacement * Pixel Density) / PixelDensity&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we round down using Floor to whole units to eliminate sub pixel positioning (which causes smoothing to the sprite)&lt;/li&gt;
&lt;li&gt;Divide by PixelDensity to convert back to UV space for texture sampling&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F080uul9e4r8rf400qd3r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F080uul9e4r8rf400qd3r.png" alt=" " width="800" height="338"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27thfcty1w2htfm9tt8r.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F27thfcty1w2htfm9tt8r.gif" alt=" " width="760" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;First one uses pixel density of value 90, as we can see it’s way crispier than the other two, last one is very smooth which I don’t want in my current game so I’ve decided to go with a value of 300 which adds a little bit of pixelated aesthetic to it.&lt;/p&gt;

&lt;p&gt;Combine all values to assign to our texture UV&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosufazert4jsuzstzmda.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fosufazert4jsuzstzmda.png" alt=" " width="800" height="471"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fake Light Effect&lt;/p&gt;

&lt;p&gt;For adding a shadow effect I Just decided to add fake light and shadow wave on the fabric &lt;/p&gt;

&lt;p&gt;we use the WaveDisplacement value for creating such effect.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Apply absolute to the WaveDisplacement value to remove -ve values and just focus on the peaks and valleys of the wave&lt;/li&gt;
&lt;li&gt;Use Power to soften the values a little bit since it’s a shadow &amp;amp; light effect&lt;/li&gt;
&lt;li&gt;Multiply just to control the intensity&lt;/li&gt;
&lt;li&gt;Add to set minimum brightness&lt;/li&gt;
&lt;li&gt;Lastly we multiply it with the SampleTextrue2D RGBA&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Dview%26id%3D178yeUBopIS7fTToDO5iTw3FDd2mhms_B" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdrive.google.com%2Fuc%3Fexport%3Dview%26id%3D178yeUBopIS7fTToDO5iTw3FDd2mhms_B" alt="FakeLight" width="1423" height="421"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;1st rug fake light values are set to zero which disables this part of the shader, 2nd simulates a little bit of dim light and shadow using low values for the wave, 3rd uses a higher LightMultiplay value.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmt0x7i65n8674kx34zy.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frmt0x7i65n8674kx34zy.gif" alt=" " width="760" height="570"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This concludes my simple approach to animating rug sprites using a shader.&lt;br&gt;
Thanks for reading! Tips and feedback are always welcome.&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://store.steampowered.com/app/4241880/Alchemy_Tunes/" rel="noopener noreferrer"&gt;Alchemy Tunes&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Pixel art by &lt;a href="https://kenmi-art.itch.io/" rel="noopener noreferrer"&gt;https://kenmi-art.itch.io/&lt;/a&gt; &amp;amp; &lt;a href="https://franuka.itch.io/" rel="noopener noreferrer"&gt;https://franuka.itch.io/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>shader</category>
      <category>programming</category>
      <category>unity3d</category>
      <category>gamedev</category>
    </item>
    <item>
      <title>Quick Guide: Voice Manipulation Using Dissonance &amp; FMOD In Unity</title>
      <dc:creator>Sara</dc:creator>
      <pubDate>Wed, 21 May 2025 23:38:55 +0000</pubDate>
      <link>https://dev.to/sarasol/quick-guide-voice-manipulation-using-dissonance-fmod-in-unity-53la</link>
      <guid>https://dev.to/sarasol/quick-guide-voice-manipulation-using-dissonance-fmod-in-unity-53la</guid>
      <description>&lt;p&gt;I have been going back to Lethal Company every once in a while and I’ve been fascinated by a lot of features in this game as a player and a developer. For this blog, I wanted to focus on one of my favourite features and it’s how voice chat manipulation is implemented technically. So I thought recreating it myself will be a fun challenge.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tools:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Main tools I loved working with and investing in for this technical implementation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dissonances VOIP: Lethal Company uses this asset so It’s pretty reliable and seems to integrate to any project just fine. It supports lots of network solutions too so it gives you flexibilty in your choices.&lt;/li&gt;
&lt;li&gt;FMOD For Unity: It has a really nice learning curve and any developer can set it up easily. It was my first time using FMOD but I didn’t have any problems checking documentation and adding audio myself.&lt;/li&gt;
&lt;li&gt;Dissonance For FMOD: Luckily, there is an integration already made for FMOD playback&lt;/li&gt;
&lt;li&gt;Fishnet SDK: There are multiple networking solutions out there but I have experience with fishnet and it integerates well with Dissonance. In addition, It’s an open source solution &amp;amp; supported by an active community which makes it reliable for me.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Approach:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FMOD voice playback integration routes players voice through an audio bus in FMOD, so we can add any effect to that audio bus. My initial thought process was to create a specific Voice bus for players and then manipulate audio through adding effects to the bus, however it didn’t seem as dynamic as I wanted.&lt;/p&gt;

&lt;p&gt;To Create a voice bus on FMOD:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Window→Mixer&lt;/li&gt;
&lt;li&gt;Create VoiceChat bus&lt;/li&gt;
&lt;li&gt;Add VoiceChat path to FMOD Bus playback as bus:/VoiceChat&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b0xcue5bxz9mly3jdo1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b0xcue5bxz9mly3jdo1.png" alt=" " width="707" height="744"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Second approach is going a step backward in the voice emitting route and checking the channel before it reaches the bus. Since FMOD playback instantiates a unique instance for each player, that means we can use each channel (per player) and apply effects on it before routing to the VoiceChat bus. Then it gives us the flexiblity we need.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6290x9znhmia53u76a3d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6290x9znhmia53u76a3d.png" alt=" " width="200" height="101"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg471ops12wwsxhjghxt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fxg471ops12wwsxhjghxt.png" alt=" " width="728" height="637"&gt;&lt;/a&gt;&lt;br&gt;
&lt;strong&gt;Implementation Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instantiating a player-specific channel made everything easier, so firstly I stored the FMOD voice playback channel for each player
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetVoicePlaybackDictionary&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="n"&gt;fmodVoicePlaybacks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="n"&gt;fmodVoicePlaybacks&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;dissonanceSetup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetComponentsInChildren&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;FMODVoicePlayback&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;().&lt;/span&gt;&lt;span class="nf"&gt;ToList&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="n"&gt;FMODVoicePlayBackDictionary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Clear&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;

    &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;voicePlayBack&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;fmodVoicePlaybacks&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;FMODVoicePlayBackDictionary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;TryAdd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;voicePlayBack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;PlayerName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;voicePlayBack&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;Once channels are mapped to players, we can dynamically add or remove effects according to the game mechanics&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This leaves us with the last step, modifying the channel based on the player state (e.g., adding reverb in specific zones).&lt;/p&gt;

&lt;p&gt;To add an effect to a channel we need to create DSP effect and use addDSP() method to the player’s channel&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;AddChannelEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dsp&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;GetEchoEffect&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
        &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addDSP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;FMOD&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CHANNELCONTROL_DSP_INDEX&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;HEAD&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dsp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DSP&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nf"&gt;GetEchoEffect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dspEffectList&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DSP&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
     &lt;span class="nf"&gt;CreateDspEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DSP_TYPE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SFXREVERB&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dspEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

     &lt;span class="n"&gt;dspEffectList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dspEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
     &lt;span class="nf"&gt;SetEchoEffectParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dspEffect&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

     &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;dspEffectList&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;SetEchoEffectParams&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DSP&lt;/span&gt; &lt;span class="n"&gt;dspEffect&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dspEffect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setParameterFloat&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="n"&gt;FMOD&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DSP_SFXREVERB&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;DECAYTIME&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;2.0f&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Removing the Effect would require the DSP type to remove from the channel (e.g., DSP_TYPE.SFXREVERB&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight csharp"&gt;&lt;code&gt;    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;GetDspEffects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SfxEffectType&lt;/span&gt; &lt;span class="n"&gt;sfxEffectType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DSP_TYPE&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dsp_types&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="n"&gt;dsp_types&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DSP_TYPE&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;();&lt;/span&gt;
        &lt;span class="k"&gt;switch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sfxEffectType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;SfxEffectType&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Echo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
                &lt;span class="n"&gt;dsp_types&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;DSP_TYPE&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SFXREVERB&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;


    &lt;span class="k"&gt;public&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="nf"&gt;RemoveChannelEffect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Channel&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;SFXEffectsManager&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SfxEffectType&lt;/span&gt; &lt;span class="n"&gt;effectType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nf"&gt;GetDspEffects&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;effectType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="n"&gt;List&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;DSP_TYPE&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;dsp_types&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dspType&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;dsp_types&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getNumDSPs&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;numDSPs&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="p"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;numDSPs&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;++)&lt;/span&gt;
            &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getDSP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dsp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;dsp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getType&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;out&lt;/span&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

                &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="p"&gt;!=&lt;/span&gt; &lt;span class="n"&gt;dspType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;continue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

                &lt;span class="n"&gt;channel&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;removeDSP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dsp&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
                &lt;span class="n"&gt;dsp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;release&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This concludes how all these tools were very easy to integrate together and made me reach my goal  in the quickest way possible.&lt;/p&gt;

&lt;p&gt;A demo if anyone wants to try adding dsp through channels without dissonance.&lt;br&gt;
&lt;a href="https://github.com/SaraAkmal/Unity-FMOD-DSPEffects-Demo" rel="noopener noreferrer"&gt;https://github.com/SaraAkmal/Unity-FMOD-DSPEffects-Demo&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Check out &lt;a href="https://store.steampowered.com/app/4241880/Alchemy_Tunes/" rel="noopener noreferrer"&gt;Alchemy Tunes&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Thanks for reading! Tips and feedback are super welcome.&lt;/p&gt;

</description>
      <category>gamedev</category>
      <category>programming</category>
      <category>unity3d</category>
    </item>
  </channel>
</rss>
