Creating dynamic sounds with FMOD

From Heroes of Hammerwatch wiki
Jump to: navigation, search

It is possible to create dynamic sounds and music for you mod using parameters in FMOD.

This page assumes you already have FMOD set up for your Heroes of Hammerwatch mod. See Adding custom sounds and music for more information.



Adding a parameter to your sound event in FMOD

1. Open your event in FMOD and use the "+" tab above the tracks to add a new parameter.

AddingFmodParameter.png


2. If you haven't created the effect that you want to be dynamic, go ahead and do that now.

NOTE: your effect must come before (on the left of) the Spatializer (the effect with 'distance attenuation') if using a 3dEvent!

AddingFmodEffect.png


3. Right-click on the knob that you want to be dynamically controlled, and select "Add Automation". Your should now see a track for that setting in the track deck.

In the new tab for your parameter, add you desired control points to determine how the setting is changed based on the parameter. There is a scale above the tracks showing the range of your parameter, and above that is a knob for your parameter to test how different values sound.You can also set a default value by right clicking on your parameter knob.

ParameterTabExample.png

Controlling the parameter in your mod scripts

You will need to use you own sValue parameter rather than the standard ones. For example: If you are creating a new projectile unit and want to have a dynamic shoot sound, do not use the "shoot-snd" parameter because this used by the base projectile classes and would be difficult to alter how it is controlled.

BAD:

<string name="shoot-snd">{5567e7f1-bf44-420c-a7b8-fc8c1ee2f628}</string>

GOOD:

<string name="custom-shoot-snd">{5567e7f1-bf44-420c-a7b8-fc8c1ee2f628}</string>

Continuing with the dynamic shoot sound example, you would need to have a custom projectile script that extends the desired type of projectile. Load in your sound sVal parameter, override the Initialize method, call the base class' Initialize method, then play your sound by calling PlaySound3D with a dictionary of your parameter:

class DynamicSoundBeam : BeamProjectile
{
	SoundEvent@ customShootSound;
	
	DynamicSoundBeam(UnitPtr unit, SValue& params)
	{
		super(unit, params);
		
		@customShootSound = Resources::GetSoundEvent(GetParamString(unit, params, "custom-shoot-snd", false));
	}
	
	void Initialize(Actor@ owner, vec2 dir, float intensity, bool husk, Actor@ target, uint weapon) override
	{
		BeamProjectile::Initialize(owner, dir, intensity, husk, target, weapon);

		float paramValue = 0.7 // <---- your beautiful dynamic parameter logic here

		dictionary params = { { "MyParameter", paramValue } };
		PlaySound3D(customShootSound, m_unit.GetPosition(), params);	
	}
}

Controlling an on-going sound

It is also possible to control an FMOD parameter while the sound is playing. Instead of using PlaySound3D, you can call PlayTracked directly on your SoundEvent which will return a SoundInstance. With a reference to the SoundInstance you can execute more control over how the sound plays out. See the SoundInstance documentation for all the options. Then you can alter the sound instance as you please in an update method:

class DynamicSoundBeam : BeamProjectile
{
	SoundEvent@ customShootSound;
	SoundInstance@ = myCustomSoundInstance;
	
	DynamicSoundBeam(UnitPtr unit, SValue& params)
	{
		super(unit, params);
		
		@customShootSound = Resources::GetSoundEvent(GetParamString(unit, params, "custom-shoot-snd", false));
	}
	
	void Initialize(Actor@ owner, vec2 dir, float intensity, bool husk, Actor@ target, uint weapon) override
	{
		BeamProjectile::Initialize(owner, dir, intensity, husk, target, weapon);
		
		@myCustomSoundInstance = customShootSound.PlayTracked(m_unit.GetPosition());
	}
	
	void Update(int dt) override
	{
		BeamProjectile::Update(dt);
		
		float param = 0.7 // <--- you got this, champ.
		
		myCustomSoundInstance.SetPosition(m_unit.GetPosition());
		myCustomSoundInstance.SetParameter("myParameter", param);
	{
}