Search Unity

Footstep sounds: Getting realistic timing

Discussion in 'Audio & Video' started by ArachnidAnimal, Nov 15, 2015.

  1. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    When I started implementing footstep sounds. I was using the principle that if a player's speed is doubled, then the footstep frequency is doubled. however, THIS IS NOT WHAT HAPPENS IN REAL LIFE.

    Actually, I did some research and found out the biggest factor is that when people walk faster, they have a larger stride, so the frequency of the footsteps audio is not a linear relation to the speed.
    I found an interesting chart at
    http://runblogger.com/2011/09/running-speed-human-variability-and.html
    made by someone who studied the phenomenon of human movement.
    Here is a chart I modded which shows what happens:

    speedVsStride.png

    As the player's speed increases, the footsteps per minute increase following the red line.

    To reverse engineer the chart to create an equation of the graph, I used:
    http://www.analyzemath.com/parabola/three_points_para_calc.html
    This generated the following equation:

    stepsPerMinute = ax^2 + bx + c, where

    a = 0.24f;
    n = 2.0f;
    b = 1.68f;
    c = 159.0f;

    Using this in a code:

    Code (csharp):
    1.  
    2. const float a = 0.24f;
    3. const float n = 2.0f;
    4. const float b = 1.68f;
    5. const float c = 159.0f
    6.  
    7. float mappedPlayerSpeed = playerVelocity / 10.0f; //Convert the speed so that walking speed is about 6
    8. float stepsPerSecond = ((a * Mathf.Pow(mappedPlayerSpeed, n)) + (b * mappedPlayerSpeed) + c) / 60.0f;
    9. float timePerStep = (1.0f / stepsPerSecond);
    10. float currentFootstepsWaitingPeriod = timePerStep; //Amount of time to wait before playing the next audio source
    11.  
    The result is when a player has a speed, you can calculate the amount of time to wait before playing another footstep audio file.

    All you really need to do is figure out the "mappedPlayerSpeed" so that when walking, the value is around 6.
    For running, it would be around 12.



    j
     
  2. hippocoder

    hippocoder

    Digital Ape

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Why wouldn't you do what presumably any game does: add a sound when the foot lands on the ground. Why would you desync it so much with approximated guesses?
     
  3. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    How would you know when a foot hits the ground in a FPS when there is no character?
     
  4. JackPowell

    JackPowell

    Joined:
    May 18, 2013
    Posts:
    6
    In the past I have added this kind of delay offset to footsteps using Wwise and best guessed the timings, but this could be useful for people building their own audio engine.

    I'm working on footsteps for a linear piece of FPS gameplay and think the graph could help me out. Thanks!

    What about timings for walking backwards and strafing?
     
  5. ArachnidAnimal

    ArachnidAnimal

    Joined:
    Mar 3, 2015
    Posts:
    1,815
    The problem is when the player runs at 4-5 times the speed of walking is when footsteps rate start sounding stupid.
    It will sound like someone is tap-dancing across the map. This is why the graph and the functions is helpful

    What I do is have an invokeRepeating function called a 5 times a second which Estimates the player's speed.
    So it would work for any player movement direction.
    (You have to adjust the values based on your project scales).

    Code (csharp):
    1.  
    2. float lastFootstepPlayedTime;
    3. Vector3 lastPlayerPosition;
    4. float VELOCITY_POLL_PERIOD = 0.2f; // 5 times a second
    5.  
    6. public void Start()
    7. {
    8.           InvokeRepeating("EstimatePlayerVelocity_InvokeRepeating", 1.0f, VELOCITY_POLL_PERIOD);
    9. }
    10.  
    11. public void EstimatePlayerVelocity_InvokeRepeating()
    12.    {
    13.    
    14.      float distanceMagnitude = (playerPosition - lastPlayerPosition).magnitude;
    15.      lastPlayerPosition = playerPosition;
    16.      float estimatedPlayerVelocity = distanceMagnitude / VELOCITY_POLL_PERIOD;    
    17.      if (estimatedPlayerVelocity < 15.0f)
    18.      {
    19.         //Avoid playing footsteps audio for moving at very small speeds
    20.         //As the human foot moves forward, the head (camera) moves forward before the foot hits the ground
    21.         //because the current foot on the ground pushes the body forward.
    22.        currentFootstepsWaitingPeriod = Mathf.Infinity;
    23.        return;
    24.      }
    25.  
    26.      const float a = 0.24f;
    27.      const float n = 2.0f;
    28.      const float b = 1.68f;
    29.     float mappedPlayerSpeed = estimatedPlayerVelocity / 10.0f; //Convert the speed so that walking speed is about 6
    30.      stepsPerSecond = ((a * Mathf.Pow(mappedPlayerSpeed, n)) + (b * mappedPlayerSpeed) + c) / 60.0f;
    31.      timePerStep = (1.0f / stepsPerSecond);  
    32.      currentFootstepsWaitingPeriod = timePerStep;
    33.  
    34.   public void Update()
    35.    {
    36.    
    37.      if (Time.time - lastFootstepPlayedTime > currentFootstepsWaitingPeriod)
    38.      {
    39.  
    40.        //Play another footstep  audio file
    41.         //...
    42.        lastFootstepPlayedTime = Time.time;
    43.      }
    44.    
    45.    }
    46.  
    47.