Calculating average keystroke speed

Hi. I’m not really sure how to word this, sorry! I’m making a cycling game and being able to measure the speed at which the player is “pedaling” is very important. I’ve made a start, but it just doesn’t look right and leads to very weird in-game behaviour.

The player presses the arrow keys left and right to pedal. Each keystroke is a half revolution of the pedals. The cadence is the average speed of full revolutions of the pedals, if that makes sense. Here’s what I have so far.

void Start ()
    {
        lastPedal = "none";
        halfRev = 0;
        rpm = 0;

        //Count rpm
        StartCoroutine(startCadenceCalc());

    }

void Update ()
    {

       if(Input.GetKeyDown(KeyCode.LeftArrow) && lastPedal != "left")
        {
           halfRev += 1;
           lastPedal = "left";
        }
        if (Input.GetKeyDown(KeyCode.RightArrow) && lastPedal != "right")
        {
            halfRev += 1;
            lastPedal = "right";
        }
    }
IEnumerator startCadenceCalc()
    {
        StartCoroutine(cadenceCalc1());
        yield return new WaitForSeconds(1);
        StartCoroutine(cadenceCalc2());
        yield return new WaitForSeconds(1);
        StartCoroutine(cadenceCalc3());
        yield return new WaitForSeconds(1);
        StartCoroutine(cadenceCalc4());
        yield return new WaitForSeconds(1);
        StartCoroutine(cadenceCalc5());
        yield return new WaitForSeconds(1);
        StartCoroutine(cadenceCalc6());
        yield return new WaitForSeconds(1);
    }

    IEnumerator cadenceCalc1()
    {
        int currentRev1 = halfRev;
        yield return new WaitForSeconds(6);
        rpm =  (halfRev - currentRev1) * 2;
        StartCoroutine(cadenceCalc1());
    }
    IEnumerator cadenceCalc2()
    {
        int currentRev2 = halfRev;
        yield return new WaitForSeconds(6);
        rpm = (halfRev - currentRev2) * 2;
        StartCoroutine(cadenceCalc2());
    }
    IEnumerator cadenceCalc3()
    {
        int currentRev3 = halfRev;
        yield return new WaitForSeconds(6);
        rpm = (halfRev - currentRev3) * 2;
        StartCoroutine(cadenceCalc3());
    }
    IEnumerator cadenceCalc4()
    {
        int currentRev4 = halfRev;
        yield return new WaitForSeconds(6);
        rpm = (halfRev - currentRev4) * 2;
        StartCoroutine(cadenceCalc4());
    }
    IEnumerator cadenceCalc5()
    {
        int currentRev5 = halfRev;
        yield return new WaitForSeconds(6);
        rpm = (halfRev - currentRev5) * 2;
        StartCoroutine(cadenceCalc5());
    }
    IEnumerator cadenceCalc6()
    {
        int currentRev6 = halfRev;
        yield return new WaitForSeconds(6);
        rpm = (halfRev - currentRev6) * 2;
        StartCoroutine(cadenceCalc6());
    }

I have multiple calculations to update the average calculation every second rather than every 6 seconds.

I know the code is very bad, but I really don’t know how to start on improving it and I’m not really sure how to word it for a Google search.

Any help on how to do this or where to look?
Thanks.

Time.deltaTime is the actual time between frames and the limitation of how fast you can capture inputs unless you do something crafty with a multithreaded solution. (basically your input rate is limited to your fps)

Better solution might look something like this?

    public enum PedalSide { Left, Right }

    private PedalSide m_leg;
    private const float KeystrokeValue = 0.5f;
    private float m_strokes;

    private void Update()
    {
        if (Input.GetKeyDown(KeyCode.LeftArrow) && m_leg == PedalSide.Left)
        {
            m_leg = PedalSide.Right;
            m_strokes += KeystrokeValue;

        }
        else if (Input.GetKeyDown(KeyCode.RightArrow) && m_leg == PedalSide.Right)
        {
            m_leg = PedalSide.Left;
            m_strokes += KeystrokeValue;
        }
    }

Either way, you don’t need the coroutines.

2 Likes

Beautiful answer by LaneFox. Now you would simply get the average cycles in a second by dividing the m_strokes by the number of seconds passed since the player started cycling.

2 Likes

Wow… you work so hard on something with a really complicated solution that doesn’t even work, then you find out the solution is so simple!

Thanks a lot, this really helps.

2 Likes

I’m having a little trouble again… the average needs to be constantly updating, preferably pretty quickly. How would I achieve this? That’s what I struggled with last time, hence so many coroutines. I had each one timing for 6 seconds to get more accuracy, and I had 6 of them so it updated ever second.

Hi, I haven’t checked the forum for a while, do you still need help?