Search Unity

Question Why are my sounds playing with no delay even though I have WaitForSeconds in the script?

Discussion in 'Scripting' started by truederfor11, Apr 16, 2021.

  1. truederfor11

    truederfor11

    Joined:
    Apr 11, 2021
    Posts:
    23
    Hey!
    I'm trying to make a script that will play footstep sounds when my player is moving, but instead of playing them every 1 second it plays them right after each other, even though I have WaitForSeconds set to delay by 1 second. How do I fix that?

    P.S. I know my code isn't pretty, is there a way to do what I'm trying to do without 5 else if statements?

    code:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class FootstepSounds : MonoBehaviour
    6. {
    7.     public AudioClip Footstep1;
    8.     public AudioClip Footstep2;
    9.     public AudioClip Footstep3;
    10.     public AudioClip Footstep4;
    11.     public AudioClip Footstep5;
    12.     public AudioSource source;
    13.     public GameObject Player;
    14.     private bool ShouldPlay = true;
    15.     private int cs;
    16.     // Start is called before the first frame update
    17.     void Start()
    18.     {
    19.        
    20.     }
    21.  
    22.     // Update is called once per frame
    23.     void Update()
    24.     {
    25.         if(Player.GetComponent<Rigidbody>().velocity != new Vector3 (0, 0, 0))
    26.         {
    27.            StartCoroutine(PlaySound());
    28.         }
    29.     }
    30.  
    31.     IEnumerator PlaySound()
    32.     {
    33.         if(ShouldPlay == true)
    34.         {
    35.          ShouldPlay = false;
    36.          cs = Random.Range(1, 7);
    37.             if(cs == 1)
    38.         {
    39.             source.PlayOneShot(Footstep1);
    40.         } else if (cs == 2)
    41.         {
    42.             source.PlayOneShot(Footstep2);
    43.         } else if (cs == 3)
    44.         {
    45.             source.PlayOneShot(Footstep3);
    46.         } else if (cs == 4)
    47.         {
    48.             source.PlayOneShot(Footstep4);
    49.         } else if (cs == 5)
    50.         {
    51.             source.PlayOneShot(Footstep5);
    52.         }
    53.         }
    54.         yield return new WaitForSeconds(1);
    55.         ShouldPlay = true;
    56.  
    57.     }
    58.  
    59. }
    60.  
     
  2. Magnesium

    Magnesium

    Joined:
    Sep 14, 2014
    Posts:
    179
    Hello,

    Here, you are creating multiple coroutines. They wont execute after each other, they are executed pretty much at the same time. I would probably not use coroutines for this but use a timer that grows whenever the rigidbody has velocity and play the sound every time it reaches a second.
     
  3. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304
    Could look more like this

    Code (CSharp):
    1. public class FootstepSounds : MonoBehaviour
    2. {
    3.     public AudioClip[] Footsteps;
    4.     public AudioSource Source;
    5.     public GameObject Player;
    6.     public Rigidbody PlayerRigidBody;
    7.  
    8.     public double TimeSinceStep = 1d;
    9.     public double StepCooldownTime = 1d;
    10.  
    11.     public float MinPitch = 0.9f;
    12.     public float MaxPitch = 1.1f;
    13.  
    14.     // Start is called before the first frame update
    15.     void Start()
    16.     {
    17.         //cache the player rigidbody so we only fetch it once
    18.         PlayerRigidBody = Player.GetComponent<Rigidbody>();
    19.     }
    20.  
    21.     // Update is called once per frame
    22.     void Update()
    23.     {
    24.         //Add time passed since the last step
    25.         TimeSinceStep += Time.deltaTime;
    26.  
    27.         //Is the player moving and have we surpassed the cooldown time?
    28.         if (PlayerRigidBody.velocity != new Vector3(0, 0, 0) && StepCooldownTime - TimeSinceStep < 0d)
    29.         {
    30.             //Fetch a random number between 0 and the number of elements in the array
    31.             int rndFootstep = Random.Range(0, Footsteps.Length);
    32.  
    33.             //RandomizePitch
    34.             float rndPitch = Random.Range(MinPitch, MaxPitch);
    35.             Source.pitch = rndPitch;
    36.  
    37.             Source.PlayOneShot(Footsteps[rndFootstep]);
    38.  
    39.             //reset the timer
    40.             TimeSinceStep = 0d;
    41.         }
    42.     }
    43. }
     
    Last edited: Apr 16, 2021
  4. truederfor11

    truederfor11

    Joined:
    Apr 11, 2021
    Posts:
    23
    Thanks for the help! The code doesn't seem to work tho and gives the follwing console error:


    IndexOutOfRangeException: Index was outside the bounds of the array.
    FootSoundsNew.Update () (at Assets/FootSoundsNew.cs:41)


    Know how to fix this?

    EDIT nvm got it fixed
     
    Last edited: Apr 18, 2021
  5. Hikiko66

    Hikiko66

    Joined:
    May 5, 2013
    Posts:
    1,304
    Add some footstep audioclips to the audioclip array in the inspector

    This is the audioclip array
    Code (CSharp):
    1. public AudioClip[] Footsteps;
    Find it on the inspector
    Click the arrow on the left of the field to display the contents of the array

    Click the + to add an element to the array
    Drag an audio clip into the new element

    Add as many footstep audioclips as you need
     
    Last edited: Apr 18, 2021