Footstep Audio Issue

I’m playing around with the footstep audio in my game to try to get things sounding a little more realistic. I’ve started out with what I thought was a pretty simple idea, but it isn’t working and I’m stumped as to why.

I have this Update function:

void Update()
{
	if (isMoving)
	{
		if (!audio.isPlaying)
		{
			int footstepSound = UnityEngine.Random.Range(1, 5);
			
			Debug.Log(footstepSound);
			
			switch (footstepSound)
			{
				case 1:
					audio.PlayOneShot(soundFootstep1);
					break;
				case 2:
					audio.PlayOneShot(soundFootstep2);
					break;
				case 3:
					audio.PlayOneShot(soundFootstep3);
					break;
				case 4:
					audio.PlayOneShot(soundFootstep4);
					break;					
			}
		}
	}
}

And this portion of code comes from one of the movement functions:

isMoving = true;

while (t <= (1.0f + ((partyObject.partyOverloaded) ? stepPauseDurationEncumbered : stepPauseDuration)))
{
    t += Time.deltaTime * (moveSpeed / gridSize);
    transform.position = Vector3.Lerp(startPosition, endPosition, Mathf.SmoothStep(0.0f, 1.0f, t));
    yield return null;
}

isMoving = false;

When I move though, I see about 30 entries in the Console from that Debug.Log, and no audio plays.

I have sounds assigned to the AudioClips (soundFootstep1, soundFootstep2, etc) and there is an AudioSource on this object.

Can anyone spot why this wouldn’t work?

Anyone have any thoughts on this? I can work around it a bunch of ways, but I’m just curious why this doesn’t work (as is).

EDIT: just to clarify the goal - play end-to-end random footsteps sounds for as long as the player is moving.

Another update to this. Still looking for advice.

What’s happening now is that the audio plays, but it’s basically hundreds of the sounds all playing at once.

What I’m expecting to happen is that it will play the random footstep sounds one after another.

For example, say the total movement action takes 3 seconds, and each sound is 1 second long. Shouldn’t it start playing the first sound, causing isPlaying to be set to true for the next 1 second. Then play the next sound, again “blocking” further sounds for 1 second. And then finally, play one last sound in the third second?

It seems like the way it’s working at the moment, isPlaying is always false regardless of whether or not there is a sound playing.

I suggest to time your step sound, using a global variable that holds the time left till the end of audio clip played. Decrease this variable in Update with Time.deltaTime and only initiate another random sound when this variable is zero or less than zero. Then reinitialize this variable with audio clip length.

IIRC audio.isPlaying() will return false if you fire off a audio.PlayOneShot(), so your footsteps are being triggered over and over again.

steveJ try playing only one sound, and to make it sound differently add the “Random” and the “Pitch” with a range od (-2, 2). so when you take steps the sound will be different in pitch, sometimes high or sometimes low. so you could use one sound

So PlayOneShot() does not affect the state of isPlaying at all?

I dont think so, had the same problem in one of my games. I switched to using audio.Play() - it will stop anyways. And then i put it into a coroutine with a timer based on my running speed. Worked pretty great.

OK, cool. This does what I originally set out to do. It’s not as nice as I thought it would be though, so it’s back to the drawing board.

Thanks all for the help :slight_smile:

private void Update()
{
	if (isMoving)
	{
		if (!audio.isPlaying)
		{
			int footstepAudio = UnityEngine.Random.Range(1, 5);
			
			switch (footstepAudio)
			{
				case 1:
				{
					audio.clip = soundFootstep1;
					audio.Play();
					break;
				}
				case 2:
				{
					audio.clip = soundFootstep2;
					audio.Play();
					break;
				}
				case 3:
				{
					audio.clip = soundFootstep3;
					audio.Play();
					break;
				}
				case 4:
				{
					audio.clip = soundFootstep4;
					audio.Play();
					break;
				}					
			}
		}
	}
}

Try using coroutines for timing the footsteps :wink: