- Home /
Change sound depending on material
Okay, I know this has been asked before, and I think I have gone through every thread I could find.
Is there a way to be able to play a loopable footstep sound that changes depending on which material the player is on?
I have tried some different solutions.
A raycast that checks which material the players is on and change the sound depending on that. My problem when was that it started my sound over and over and over again, at the same time so it did not work. My workaround for this was to use a bool to see if footstep sound was playing or not, and if not play one. This worked, but then when I changed material it did not change from the last sound it played.
Same thing but with a OnCollisionStay, then I had the same problem. It did not change the sound when switching material, or it started the sound over and over again.
So I have used this solution for now (see code below), but it far from perfect working. It has problem sometimes changing the sound, and sometimes starts the sound twice and so on.
So now my question is: Does anyone have a better solution for me with this? There must be a good way of doing this in Unity.
Thanks in advance.
void OnCollisionEnter(Collision colPlayer)
{
bPlayingFootStepSound = false;
}
void OnCollisionExit(Collision colPlayer)
{
bPlayingFootStepSound = false;
}
/// <summary>
/// Use player collision on ground to see which sounds to use on which material
/// </summary>
/// <param name="colPlayer"></param>
void OnCollisionStay(Collision colPlayer)
{
if (bPlayingFootStepSound == false)
{
bPlayingFootStepSound = true;
if (colPlayer.gameObject.tag == "Grass")
{
audio.clip = a_GrassFootsteps;
audio.loop = true;
audio.Play();
}
else if (colPlayer.gameObject.tag == "Dirt")
{
audio.clip = a_DirtFootsteps;
audio.loop = true;
audio.Play();
}
else if (colPlayer.gameObject.tag == "Leaf")
{
audio.clip = a_LeafFootsteps;
audio.loop = true;
audio.Play();
}
else if (colPlayer.gameObject.tag == "Gravel")
{
audio.clip = a_GravelFootsteps;
audio.loop = true;
audio.Play();
}
else if (colPlayer.gameObject.tag == "Concrete")
{
audio.clip = a_ConcreteFootsteps;
audio.loop = true;
audio.Play();
}
}
}
public void StopFootStep()
{
if (bPlayingFootStepSound == true)
{
bPlayingFootStepSound = false;
audio.Stop();
}
}
FYI, you're doing it based on the GameObject's tag not material as you mention in your OP.
Answer by jbecana · Mar 16, 2014 at 06:16 PM
I would disable the loop flag in the audioclip and move the if statements to OnCollisionEnter(), to play the sound just once when player hits ground. Also remove the OnCollisionStay and OnCollisionExit calls. That means your player should move up and down a bit when walking or running. Or you could actívate the sound with your speed if you are using a rigidbody.
Another solution is playing the sound based on the player movement. Based on bobStepCounter being multiple of a value, use PlayClipAtPoint.
// Calculate bob movement only if we are walking
if ( isWalking )
{
// Only count steps if player is grounded
if ( isGrounded )
{
bobStepCounter += Vector3.Distance ( lastPlayerPosition, transform.position ) * bobWalkSpeed;
}
}
I tried that. The only problem then was that when the player stops on a material the footstep sounds did not start again until they entered a new material, that would say started a new collision.
$$anonymous$$aybe it is possible to keep using this in OnCollisonStay?
If you move your player slightly up and down as one would do while stepping, say twice a second, you would enter a new collision pretty soon. For another solution, I put in the answer some lines from a tutorial I did long ago but never finished
Your answer
![](https://koobas.hobune.stream/wayback/20220613140406im_/https://answers.unity.com/themes/thub/images/avi.jpg)
Follow this Question
Related Questions
3d animation controller 0 Answers
3D Custom Character Controller Movement Directions are going Haywire 0 Answers
Player shaking when move (not the camera) 0 Answers
Make controller able to move backwards if mouse button is held down 0 Answers
Stick player (my own rigidbody controller) to the ground when going down the slope 2 Answers