- Home /
Triggering different sounds for "footsteps" on different surfaces for a worm-like character.
Howdy! I'd like to state first that I'm an audio guy (sound design, music) that has, of this year, gotten really into wanting to learn how to do audio for games and to implement them properly into said games.
I've been digging through the forums here and elsewhere online to find different ways of triggering different sounds for when the player is on different surfaces e.g. stone, wood, grass, etc. Though with my situation, I've been going through the Tornado-Twins worm-game tutorial (some of you may be familiar with it, and again I'm quite new hence me doing said tutorials) and I've finished all the videos in the tutorial and wanting to get very detailed sound use in it. So my case I have a worm character scooting around the ground, got some water in the level with sound triggers going on and recently created a script that plays a sound when I move my character using WASD or the Arrow Keys and that mutes it when I'm not, which I feel like there is a better way in general for getting sound playing instead of attaching it to the character. Here is the simple script:
var AudioFile : AudioClip;
function Update()
{
if ( Input.GetButtonDown( "Horizontal" ) || Input.GetButtonDown( "Vertical" ) )
audio.Play();
else if ( !Input.GetButton( "Horizontal" ) && !Input.GetButton( "Vertical" ) && audio.isPlaying )
audio.Stop(); // or Pause()
}
Any suggestions would be greatly appreciated! Also, on a similar note, I could definitely learn/know more on scripting in regards to audio (and in general), does anyone know of a good source to check out to learn more about scripting (books, videos, web)? I'm not expecting to be a guru in a week I just wish to be less ignorant about game development and especially on the audio end that I'm interested in.
Thank you very much in advance for your time reading this novel of a post and for any and all help!
So I got audio working! It's just a little bit funky but if I adjust a few ti$$anonymous$$g things (since the audio triggering is a bit fast) I can get it all sounding good, I'll post the code I used to get it going below, thanks again for your time and the help!
var delayBeforeSteps : float = 0.20;
var delayBetweenSteps: float = 0.45;
var audioStepLength : float = 0.60;
var groundType : int;
var isPlayerWalking : float = 0.0;
var footAudioRandomness = 0.1;
var soundEffect$$anonymous$$chRandomness = 0.05;
function Update()
{
//Check to see if the player is walking by checking for input from the walking keys
if(Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
{
//if those keys are pressed, the player must be walking...
isPlayerWalking += Time.deltaTime;
}
else
{
//if those keys aren't pressed, the player can't be walking.....
isPlayerWalking = 0;
}
}
function Start()
{
var aSources = GetComponents(AudioSource);
footSource1 = aSources[0];
while(true)
{
if (isPlayerWalking >= 0.20 && groundType == 1)
{
yield WaitForSeconds(delayBeforeSteps);
footSource1.clip = stepTemple[Random.Range(0, stepTemple.length)];
footSource1.volume = Random.Range(0.4 - footAudioRandomness, 0.4 + footAudioRandomness);
footSource1.pitch = Random.Range(1.0 - soundEffect$$anonymous$$chRandomness, 1.0 + soundEffect$$anonymous$$chRandomness);
footSource1.Play();
if(isPlayerWalking == 0)
{
yield;
}
}
else if ( isPlayerWalking >= 0.20 && groundType == 2)
{
yield WaitForSeconds(delayBeforeSteps);
footSource1.clip = stepWood[Random.Range(0, stepWood.length)];
footSource1.volume = Random.Range(0.4 - footAudioRandomness, 0.4 + footAudioRandomness);
footSource1.pitch = Random.Range(1.0 - soundEffect$$anonymous$$chRandomness, 1.0 + soundEffect$$anonymous$$chRandomness);
footSource1.Play();
if(isPlayerWalking == 0)
{
yield;
}
}
else if ( isPlayerWalking >= 0.20 && groundType == 3)
{
yield WaitForSeconds(delayBeforeSteps);
footSource1.clip = stepStone[Random.Range(0, stepStone.length)];
footSource1.volume = Random.Range(0.4 - footAudioRandomness, 0.4 + footAudioRandomness);
footSource1.pitch = Random.Range(1.0 - soundEffect$$anonymous$$chRandomness, 1.0 + soundEffect$$anonymous$$chRandomness);
footSource1.Play();
if(isPlayerWalking == 0)
{
yield;
}
}
else if (isPlayerWalking >= 0.20 && groundType == 4)
{
yield WaitForSeconds(delayBeforeSteps);
footSource1.clip = stepGround[Random.Range(0, stepGround.length)];
footSource1.volume = Random.Range(0.4 - footAudioRandomness, 0.4 + footAudioRandomness);
footSource1.pitch = Random.Range(1.0 - soundEffect$$anonymous$$chRandomness, 1.0 + soundEffect$$anonymous$$chRandomness);
footSource1.Play();
if(isPlayerWalking == 0)
{
yield;
}
}
else
{
yield;
}
}
}
function OnControllerColliderHit (hit : ControllerColliderHit)
{
if (hit.gameObject.tag == "templeFloor")
{
groundType = 1;
print("Temple");
}
else if (hit.gameObject.tag == "woodFloor")
{
groundType = 2;
print("Wood");
}
else if (hit.gameObject.tag == "stoneFloor")
{
groundType = 3;
print("Stone");
}
else if (hit.gameObject.tag == "groundFloor")
{
groundType = 4;
print("Ground");
}
}
Answer by RoboticSarcasm · Oct 10, 2013 at 08:00 AM
I'm not exactly sure if this would work but it might be possible to have different sounds for object with different tags. For example you may be able to tag a dirt floor with a dirt-tag and play a specific sound upon contact with an object with the tag dirt.
Answer by jmatthews · Oct 10, 2013 at 03:45 AM
There's not really a "right" way to do this but some ways are more robust than others. The most robust way would be to check what your worm is colliding with (water, stone, gravel, etc..) by doing a collision check, getting the material name of the game object and then using that as an index to retrieve the proper audio for that material.
A far easier way is to set up collision areas and play whatever the appropriate sound for that area is when you move. This would be the next logical step based on what you're currently doing. Again, its not the "right" way of doing it but you can get a reasonable outcome and its a lot less intensive than building a material to audio system that could cost you 1000 lines of code and a lot of trial and error.
So set up a big box collider that covers your water and if your character collider is touching the box collider play the water sound, otherwise play the dirt sound or whatever is appropriate as a default.
Also you could experiment with audio.PlayOneShot() and just check your movement when audio isn't playing. this would keep your sound from firing 100 times per second.
Your answer
Follow this Question
Related Questions
Getting audio.PlayOneShot to work 2 Answers
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
A simple problem with scripts 1 Answer
Safe area from enemies 1 Answer
Detect collision/trigger between two body without rigidbody? 3 Answers