Footsteps variations
by Richard Marrevee · 10/28/2014 (10:22 am) · 8 comments
When playtesting the demo of my game The Master's Eye I got a little bit tired of the monotone sound of the footsteps when I was walking around the different missions (this was also ment by some community members when they watched videos of my game). Browsing through the code I found out it was fairly easy to add a little variation to it without the need to add different sounds for the same material (and without the need to add a lot of code changes).
When you look at the code in the playFootstepSound method in player.cpp, you'll notice that a footstep is played using the SFX->playOnce method using a SFXProfile defined in script. The disadvantage of this is that it plays the same sound for every single footstep which results in a very dull soundeffect, which is very unnatural imho. I have changed this playFootstepSound method a little bit by adding a random variation in pitch every time the footstepsound is played and now you have footsteps that sounds a little bit different. I have choosen to vary the pitch between 0.70 and 1.15 but this is personal.
I will not give you the changes I've made to Player::playFootstepSound but instead give you the whole new method. Just replace it with this new one, rebuild the engine and you're done. I've also made another change at the end of the method, so I am able to use more than just the 4 hardcoded sounds.
Here it is:
I hope you like it and find it useful.
Thanks.
Richard.
When you look at the code in the playFootstepSound method in player.cpp, you'll notice that a footstep is played using the SFX->playOnce method using a SFXProfile defined in script. The disadvantage of this is that it plays the same sound for every single footstep which results in a very dull soundeffect, which is very unnatural imho. I have changed this playFootstepSound method a little bit by adding a random variation in pitch every time the footstepsound is played and now you have footsteps that sounds a little bit different. I have choosen to vary the pitch between 0.70 and 1.15 but this is personal.
I will not give you the changes I've made to Player::playFootstepSound but instead give you the whole new method. Just replace it with this new one, rebuild the engine and you're done. I've also made another change at the end of the method, so I am able to use more than just the 4 hardcoded sounds.
Here it is:
void Player::playFootstepSound( bool triggeredLeft, Material* contactMaterial, SceneObject* contactObject )
{
MatrixF footMat = getTransform();
SFXSource* soundSrc;
F32 randPitch = mRandF(0.70f, 1.15f);
if( mWaterCoverage > 0.0 )
{
// Treading water.
if (mWaterCoverage < mDataBlock->footSplashHeight)
{
soundSrc = SFX->createSource(mDataBlock->sound[PlayerData::FootShallowSplash], &footMat);
soundSrc->setPitch(randPitch);
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
else
{
if ( mWaterCoverage < 1.0 )
{
soundSrc = SFX->createSource(mDataBlock->sound[PlayerData::FootWading], &footMat);
soundSrc->setPitch(randPitch);
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
else
{
if ( triggeredLeft )
{
SFX->playOnce( mDataBlock->sound[ PlayerData::FootUnderWater ], &footMat );
soundSrc = SFX->createSource(mDataBlock->sound[PlayerData::FootBubbles], &footMat);
soundSrc->setPitch(randPitch);
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
}
}
}
else if( contactMaterial && contactMaterial->mFootstepSoundCustom )
{
// Footstep sound defined on material.
soundSrc = SFX->createSource(contactMaterial->mFootstepSoundCustom, &footMat);
soundSrc->setPitch(randPitch);
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
else
{
// Play default sound.
S32 sound = -1;
if( contactMaterial && contactMaterial->mFootstepSoundId != -1 )
sound = contactMaterial->mFootstepSoundId;
else if( contactObject && contactObject->getTypeMask() & VehicleObjectType )
sound = 2;
if (sound > -1)
{
soundSrc = SFX->createSource(mDataBlock->sound[sound], &footMat);
soundSrc->setPitch(mRandF(0.5f, 2.0f));
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
else
{
soundSrc = SFX->createSource(mDataBlock->sound[PlayerData::FootHard], &footMat);
soundSrc->setPitch(randPitch);
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
/* switch ( sound )
{
case 0: // Soft
SFX->playOnce( mDataBlock->sound[PlayerData::FootSoft], &footMat );
break;
case 1: // Hard
SFX->playOnce( mDataBlock->sound[PlayerData::FootHard], &footMat );
break;
case 2: // Metal
SFX->playOnce( mDataBlock->sound[PlayerData::FootMetal], &footMat );
break;
case 3: // Snow
SFX->playOnce( mDataBlock->sound[PlayerData::FootSnow], &footMat );
break;
default: //Hard
SFX->playOnce( mDataBlock->sound[PlayerData::FootHard], &footMat );
break;
}*/
}
}I hope you like it and find it useful.
Thanks.
Richard.
About the author
Started programming in 1984 on an Oric, when time progressed switched to MSX, Amiga and finally the Windows PC with T3D. Now developing an epic fantasy game: The Master's Eye. Creator of the DoorClass pack and VolumetricFog pack @ richardsgamestudio.com
#2
10/28/2014 (7:28 pm)
This is beautiful. I was worried about this myself because I now have the levels finally laid out for my game along with the story line. I will need to soon concentrate on these types of details. Thank you!
#3
10/28/2014 (9:29 pm)
Oh great, it was on our long list of things to do; now you helped us on our way with this. Thanks @Richard!
#4
10/29/2014 (3:22 am)
this is a great resource, thanks.
#5
and add
10/29/2014 (12:16 pm)
Thinking about it again, you can do the same trick with the volume of the footsteps for more variation by using:F32 randVolume = mRandF(0.6f, 1.0f);after the line
F32 randPitch = mRandF(0.70f, 1.15f);
and add
soundSrc->setVolume(randVolume);after each
soundSrc->setPitch(randPitch);line.
#6
Here is a slight alternative if anyone is interested, it keeps the default hard coded sounds (if you actually prefer that), just add the volume stuff from above if you want it. I have also dumped the FootBubbles sound. Don't see the point in that.
11/01/2014 (4:52 am)
Hey awesome work Richard, thanks for sharing mate :)Here is a slight alternative if anyone is interested, it keeps the default hard coded sounds (if you actually prefer that), just add the volume stuff from above if you want it. I have also dumped the FootBubbles sound. Don't see the point in that.
void Player::playFootstepSound( bool triggeredLeft, Material* contactMaterial, SceneObject* contactObject )
{
SFXTrack *track = NULL;
if( mWaterCoverage > 0.0 )
{
// Treading water.
if ( mWaterCoverage < mDataBlock->footSplashHeight )
track = mDataBlock->sound[ PlayerData::FootShallowSplash ];
else
{
if ( mWaterCoverage < 1.0 )
track = mDataBlock->sound[ PlayerData::FootWading ];
else
{
if ( triggeredLeft )
{
track = mDataBlock->sound[ PlayerData::FootUnderWater ];
//Pointless having two sounds, just combine them when creating ;-)
//SFX->playOnce( mDataBlock->sound[ PlayerData::FootBubbles ], &footMat );
}
}
}
}
else if( contactMaterial && contactMaterial->mFootstepSoundCustom )
{
// Footstep sound defined on material.
track = contactMaterial->mFootstepSoundCustom;
}
else
{
// Play default sound.
// +++ Play something, not nothing!!!
S32 sound = 0;
/*
S32 sound = -1;
*/
// -->
if( contactMaterial && contactMaterial->mFootstepSoundId != -1 )
sound = contactMaterial->mFootstepSoundId;
else if( contactObject && contactObject->getTypeMask() & VehicleObjectType )
sound = 2;
switch ( sound )
{
case 0: // Soft
track = mDataBlock->sound[PlayerData::FootSoft];
break;
case 1: // Hard
track = mDataBlock->sound[PlayerData::FootHard];
break;
case 2: // Metal
track = mDataBlock->sound[PlayerData::FootMetal];
break;
case 3: // Snow
track = mDataBlock->sound[PlayerData::FootSnow];
break;
}
}
//Play track if we have one
if(track)
{
MatrixF footMat = getTransform();
F32 randPitch = mRandF(0.70f, 1.15f);
SFXSource* soundSrc = SFX->createSource(track, &footMat);
soundSrc->setPitch(randPitch);
soundSrc->play();
SFX->deleteWhenStopped(soundSrc);
}
}
#8
11/02/2014 (4:44 pm)
Great idea. 
Associate Steve Acaster
[YorkshireRifles.com]