- Home /
FPS Footstep Audio Plays Too Quickly
I am trying to add a simple footstep sound (16 bit, 44100 Hz, 00:00.498 86.9KB WAV) to an fps player using the code below. Most of this code I got from searching other posts on the subject:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (AudioSource))]
public class PlayerSound : MonoBehaviour
{
public AudioClip[] playerSounds = new AudioClip[9];
void Update()
{
PlaySound ();
}
void PlaySound()
{
if(Input.GetAxis("Vertical") != 0f)
{
audio.clip = playerSounds[0];
if(!audio.isPlaying)
{
audio.Play();
}
else if(audio.isPlaying)
{
audio.Pause ();
}
}
}
}
When I move the player forward the sound plays more rapidly than it should (far more rapidly if I use audio.Stop() in the else if statement) and seems to add a very faint echo of the accelerated sound immediately after having been played. This effectively distorts the sound just enough to present some semblance of the original audio, but not enough to accurately be called similar. I figure it must have something to do with the calling the audio clip to quickly, but I can't seem to figure out how to slow that call down. The closest I came was by doing this:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (AudioSource))]
public class PlayerSound : MonoBehaviour
{
public AudioClip[] playerSounds = new AudioClip[9];
void Update()
{
StartCoroutine(PlayWalk());
}
IEnumerator PlayWalk()
{
if(Input.GetAxis("Vertical") != 0f)
{
audio.clip = playerSounds[0];
if(!audio.isPlaying)
{
audio.Play();
}
else if(audio.isPlaying)
{
yield return new WaitForSeconds(1);
audio.Stop ();
}
}
}
}
But this was a very temporary fix. Depending on the value of the argument in the WaitForSeconds method, the sound would play as desired (without distortion and playing the entire clip) only for about the length of the value. The clip would then go silent and would not resume again for a number of seconds. Does anyone have any insight into what I might be doing wrong? Forgive me if it is something silly, but I haven't been coding for very long. Thanks.
Answer by supernat · Nov 21, 2013 at 05:10 AM
The problem is that you are starting a new coroutine in every Update frame. This will probably get into a sync where one coroutine starts the sound and the next one stops it immediately, which explains the silence. You could instead start the coroutine in the Start() method, and have it loop forever with a while (true) (I hate those usually...), and leave the rest of the code intact. It would do the footsteps while the input is held and be silent after.
Also consider using playOneShot() instead of starting and stopping the audio, because you will probably want to play multiple sounds from this same audio source. You could just play one shots, wait a second, play it again, etc.
Thanks for such a quick response. Before changing the part of the script that starts and stops the audio, I tried creating a while(true) loop containing the coroutine in the body of the Start() method as you suggested. Unfortunately, this caused Unity to "freeze". I've never been able to get a while loop to work in Unity. Here is the new code:
using UnityEngine;
using System.Collections;
[RequireComponent (typeof (AudioSource))]
public class PlayerSound : $$anonymous$$onoBehaviour
{
public AudioClip[] playerSounds = new AudioClip[9];
void Start()
{
while(true)
{
StartCoroutine(PlaySounds());
}
}
IEnumerator PlaySounds()
{
if(Input.GetAxis("Vertical") != 0f)
{
audio.clip = playerSounds[0];
if(!audio.isPlaying)
{
audio.Play();
}
else if(audio.isPlaying)
{
yield return new WaitForSeconds(1);
audio.Stop ();
}
}
}
}
You can create while loops in coroutines without a problem, but you have to make sure you yield return null at the end of te while loop. Co routines still are only expected to run a small chunk o code each frame before they yield, so I'd bet maybe you had the while loop but only yielded for the WaitForSeconds call, based on it freezing.
Awesome! That fixed it. Though I still don't quite understand why. If you have the time and the desire to explain in further detail, I would greatly appreciate it. If not, no worries. You've been a huge help. Thanks again.
Your answer
Follow this Question
Related Questions
Change player control to a target model (FPS) 0 Answers
Footsteps Script for Running and Walking 3 Answers
Sounds triggering too fast 4 Answers
The name 'Joystick' does not denote a valid type ('not found') 2 Answers
Audio: how do I immediately play a new audioclip without delay(code included)? 2 Answers