Getting audio.PlayOneShot to work

Hey there! I just ran into an issue working with audio.PlayOneShot. I want to say first I’m new to scripting, I’m an audio guy wanting to gain more knowledge about properly implementing audio into video games. So I have a script set up with triggers for different walking sounds depending on what kind of surface the character is walking on (utilizing tags). I have audio playing but it’s really fast and when my character isn’t moving it’ll loop the last step sound. I was looking to use the audio.PlayOneShot to help fix my issue but what I thought looked right in code doesn’t seem to work (either get errors or it doesn’t fix the issue, I’ve tried moving the line of code with no result). Is there another way to fix the problem or did I just place the line of code in the wrong spot? Here it is:

var stepWood:AudioClip[];
var stepTemple:AudioClip[]; // fill this array with the sounds at the Inspector
var stepStone:AudioClip[];
var stepGround:AudioClip[];

var footSource1 : AudioSource;
     
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 soundEffectPitchRandomness = 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 - soundEffectPitchRandomness, 1.0 + soundEffectPitchRandomness);
    		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 - soundEffectPitchRandomness, 1.0 + soundEffectPitchRandomness);
    		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 - soundEffectPitchRandomness, 1.0 + soundEffectPitchRandomness);
    		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 - soundEffectPitchRandomness, 1.0 + soundEffectPitchRandomness);
    		footSource1.Play();
    		
    		if(isPlayerWalking == 0)
    		{
    			yield;
    		}
    	}
		else
    	{
    		yield;
    	}   
    }
}
 
function OnControllerColliderHit (hit : ControllerColliderHit)
{
    if (hit.gameObject.tag == "templeFloor")
    {
    	groundType = 1;
    	print("Temple");
    	audio.PlayOneShot(stepTemple);
    }
    else if (hit.gameObject.tag == "woodFloor")
    {
    	groundType = 2;
    	print("Wood");
    	audio.PlayOneShot(stepWood);
    }
    else if (hit.gameObject.tag == "stoneFloor")
    {
    	groundType = 3;
    	print("Stone");
    	audio.PlayOneShot(stepStone);
    }
    else if (hit.gameObject.tag == "groundFloor")
    {
    	groundType = 4;
    	print("Ground");
    	audio.PlayOneShot(stepGround);
    }
}

Thank you very much in advance for any help!

Ok I can see you put much effort into your audio script and for the general there is nothing wrong with it, only if I where you I wouldn’t use playOneShot for a walking loop.

In my own walking script wich is kinda similar to this one I simply play when moving and pause when stopping, this way the audio will continue as soon as you are walking again. Then on the bottom lines I check the floors and switch the Audio clips. I’l give you a rough example:

var WalkAudio:AudioClip;
var stepTemple:AudioClip;

function Update (){

//Here we will detect if the walk buttons are pressed and //play the audio.
var Audio= gameObject.GetComponent(AudioSource);

   if(Input.GetButton("Horizontal") || Input.GetButton("Vertical"))
    {
       //if those keys are pressed, the player must be walking...
   Audio.Play();
    }
    else
    {
    //if those keys aren't pressed, the player can't be walking.....
     Audio.Pause();
    }


}



function OnControllerColliderHit (hit : ControllerColliderHit)
{
var Audio= gameObject.GetComponent(AudioSource);
    if (hit.gameObject.tag == "templeFloor")
    {
        groundType = 1;
        print("Temple");
        Audio.clip=stepTemple;
    }
else{
Audio.clip=WalkAudio;
}

}

Also if you are using the character controller you can check its velocity and play audio accordingly, I myself use the velocity to check how fast my character is going and switch between running walking and crouching clips. But those are extra, for what you want to achive this is a good base to start of. Good luck

Place things in your Start() that require to be executed before the general running of the script.

Place continuous function in your Update() which gets called every frame. This way you wont need a while loop, which can be dangerous anyway.

I don’t know but I think yield from a while in start sounds like disaster to me.

I think its firing super fast as its zipping round a while loop stacking up coroutines.