- Home /
Footsteps sound on collision problem, please help!!!
Hello there, i'm testing some C# scripts in Unity and in this case i'm trying to get a "Ground Detector" wich is a simple box collider parented to each player's foot, able to get tags from game objects (triggered) and play a different sounds depending on it.
I'm using the locomotor system, so with this "detector" i can obtain an effective ground detection, depending on the real foots/ground contact. Every foot get a ground tag independently, and send a command to the main Audio Source, wich play the right sound.
In some cases foots are on different surfaces (for ex: one on grass, one on concrete), and my Audio Source play the corresponding audio file correctly.
So, till this point the script works well, but sounds are a bit confusing because sometimes they're played more than one at time. Also, when running, audio seem delayed.
I think one of the problem is about multiple ground collision on each step, with produce multiple detections, and in the end multiple sound played for each step.
How to solve that?
I'm also concerned about calculations (is this the reason that cause audio delaying?)...is my method optimized?
Here's the script
using UnityEngine;
using System.Collections;
public class SoundEffectController : MonoBehaviour {
public AudioSource footAudioSource;
public AudioClip[] cementsteps;
public AudioClip[] grasssteps;
public AudioClip[] dirtsteps;
void OnTriggerEnter(Collider col){
if (col.tag == "pietra")
{
footAudioSource.PlayOneShot(cementsteps[Random.Range(0, cementsteps.Length)]);
}
else if(col.tag == "erba")
{
footAudioSource.PlayOneShot(grasssteps[Random.Range(0, grasssteps.Length)]);
}
else if(col.tag == "terra")
{
footAudioSource.PlayOneShot(dirtsteps[Random.Range(0, dirtsteps.Length)]);
}
}
}
My knowledge is limited for now, and i'm trying to understand scripts all around the web, mixing the useful parts for my purposes, so my tests are full of errors or illogical methods.
I'm new here, on UnityAnswer and in Unity coding and english is not my mothertongue, so be patient with me if you can :D.
I hope I explained it clearly.
Cheers.
don't use "else if". Generally never use it unless you are very very experience, so that's that. Try code like this:
if ( blah ... )
{
do something;
return;
}
if ( blah ... )
{
do something;
return;
}
if ( blah ... )
{
do something;
return;
}
note the "return"
Secondly it is actually very hard to write foot-fall code.
You need a STATEFUL BOOLEAN, like this
var IJusrDidAFootStepLboolean;
when you hit the ground, set it true.
after that, make a timer -- use Invoke() -- to leave it true for say 0.75 seconcds, and only then set it to false
while it is true, don't play another footfall sound
Thankyou Fattie, could you be more explicit about the stateful boolean and the timer? I undestand the logical sense of it, but i don't know how to implement it in my code.
Do you know on the web an example of that?
Answer by aldonaletto · Mar 23, 2013 at 03:38 PM
Your script seems ok, assuming that the triggers are attached to the foot bones. Maybe your problem is caused by the trigger going below the ground - this would cause a second OnTriggerEnter event, firing the spurious footstep. If this is the case, adjusting the trigger size and position may solve the problem - I would try a small sphere childed to each feet.
Besides this, adding a dead time after each footstep could help - like this:
public AudioSource footAudioSource;
public AudioClip[] cementsteps;
public AudioClip[] grasssteps;
public AudioClip[] dirtsteps;
public float stepInterval = 0.25f;
private float nextStep = 0f;
void OnTriggerEnter(Collider col){
if (Time.time > nextStep){ // no sound in the dead time
nextStep = Time.time + stepInterval; // set min time for next step
if (col.tag == "pietra"){
footAudioSource.PlayOneShot(cementsteps[Random.Range(0, cementsteps.Length)]);
}
else if(col.tag == "erba")
{
footAudioSource.PlayOneShot(grasssteps[Random.Range(0, grasssteps.Length)]);
}
else if(col.tag == "terra")
{
footAudioSource.PlayOneShot(dirtsteps[Random.Range(0, dirtsteps.Length)]);
}
}
}
Hey aldonaletto, i've followed your instructions and it worked!!!
Here's your tips integrated in my code:
using UnityEngine;
using System.Collections;
public class SoundEffectController : $$anonymous$$onoBehaviour
{
public AudioSource footAudioSource;
public AudioClip[] cementsteps;
public AudioClip[] grasssteps;
public AudioClip[] dirtsteps;
public float stepInterval = 0.25f;
private float nextStep = 0f;
void OnTriggerEnter(Collider col)
{
if(col.tag == "pietra" && Time.time > nextStep)
{
nextStep = Time.time + stepInterval;
footAudioSource.PlayOneShot(cementsteps[Random.Range(0, cementsteps.Length)]);
return;
}
if(col.tag == "erba" && Time.time > nextStep)
{
nextStep = Time.time + stepInterval;
footAudioSource.PlayOneShot(grasssteps[Random.Range(0, grasssteps.Length)]);
return;
}
if(col.tag == "terra" && Time.time > nextStep)
{
nextStep = Time.time + stepInterval;
footAudioSource.PlayOneShot(dirtsteps[Random.Range(0, dirtsteps.Length)]);
return;
}
}
}
Could you tell me it everything is ok as it seems?
Anyway, yes, there is a small sphere collider parented with each foot, and the different ground type are tagged differently and "flagged as trigger".
I'm going to post a video with an example!
Here's a video showing the script in action:
http://www.youtube.com/watch?v=G9ZrXcNuLPo
I've noticed an audio delay or latency after running for seconds...
Some advices to fix it? $$anonymous$$aybe setting a different stepInterval depending on character walk or run variables?
Your answer
Follow this Question
Related Questions
Play different sounds on different surfaces? 1 Answer
Music Zones play music with tags? 0 Answers
OnTriggerStay weird behaviour 0 Answers
Trying to play other objects' sound and animations from Raycast hit 1 Answer
Random footsteps 5 Answers