2012-03-26

Play sounds when walking

I know this has been done before and done so many times before -- goodness knows Miss Vila owned enough pairs of shoes and boots that made footstep noises, and I might have at least one pair of pony boots in my inventory that do the same. ;)

But, anyway, after having been asked a scripting question this last weekend and not knowing the answer right off, I couldn't resist having a think and a read. I found the answer and, in doing so, realised that it was easy to write a script that plays a sound when an avatar is walking. Which means I could finally make myself a subtle barefoot walking sound thing.

Which I did this morning.

This script is the result of my experimenting and I offer it here in case it's useful to anyone else. Just create a prim and drop this script in, along with the sound you want to play. Attach the prim to yourself (either as a HUD, or to some part of your body -- I've got it attached to my right foot, and made invisible) and you should be good to go.

//////////////////////////////////////////////////////////////////////
// Z&A Simple Walking Sound -- Play a sound when an avatar walks
// By Antony Fairport.
//
// Written as an experiment in reacting to llGetAnimation() return
// values (and to give me a barefoot padding sound when I'm not wearing
// any boots or shoes).
//
// I don't claim this is the best way, most efficient way, or most elegent
// way of doing this. But it's a way of doing it.
//
// Revision history:
// -----------------
//
// 2012-04-10
// Changed the code so that running is considered to be the same as
// walking. Before running was just ignored and no sound was played.
//
// 2012-03-26
// Initial revision.
//////////////////////////////////////////////////////////////////////
// Globals.
key g_kOwner;
string g_sWalking;
string g_sLastAnimation;
//////////////////////////////////////////////////////////////////////
// Default state.
default
{
//////////////////////////////////////////////////////////////////
// State entry.
state_entry()
{
// Grab the owner's key. Might as well hold it in a global
// vs call llGetOwner() evert single timer tick.
g_kOwner = llGetOwner();
// Grab the sound.
g_sWalking = llGetInventoryName( INVENTORY_SOUND, 0 );
// If we've got a sound...
if ( g_sWalking != "" )
{
// ...kick off the timer.
llSetTimerEvent( 0.2 );
}
}
//////////////////////////////////////////////////////////////////
// React to a timer event.
timer()
{
// Work out what we're doing right now.
string sAnimation = llGetAnimation( g_kOwner );
// Walking or running?
if ( ( sAnimation == "Walking" ) || ( sAnimation == "Running" ) )
{
// Wasn't walking or running last we checked?
if ( ( g_sLastAnimation != "Walking" ) && ( g_sLastAnimation != "Running" ) )
{
// Start the sound.
llLoopSound( g_sWalking, 1.0 );
}
}
// Not walking or running now but was a moment ago?
else if ( ( g_sLastAnimation == "Walking" ) || ( g_sLastAnimation == "Running" ) )
{
// Stop the sound.
llStopSound();
}
// Remember what we were doing.
g_sLastAnimation = sAnimation;
}
//////////////////////////////////////////////////////////////////
// React to changes.
changed( integer change )
{
// Has the owner, or inventory, changed?
if ( ( change & CHANGED_OWNER ) || ( change & CHANGED_INVENTORY ) )
{
// Yes. Reset the script.
llResetScript();
}
}
}
This probably isn't the most elegant way of doing this. It probably isn't the most efficient either. But it was a fun experiment and it seems to work just fine.

No comments:

Post a Comment