If the button is pressed X times in 1 second, do it?

I am wondering how to do this, if, for example, the "F" button is pressed 5 times in a second, do // something.

How so? At first I thought of doing something like this:

private float totalCount = 0f;
private float countOne = 1f;

void Update(){

    if(Input.GetKeyDown(KeyCode.F)){

        totalCount += countOne;
    }

    if (totalCount == 5){

        // do some thing
    }
}

But obviously this is not exactly what I want. So how do I achieve this? Coroutine?

+4
source share
3 answers

Rx is the perfect way to do this. You can use a simple buffer in one second.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reactive.Linq;

namespace Anything
{
    public class Program
    {
        public static void Main(string[] _)
        {
            var sw = Stopwatch.StartNew();

            Keys()
                .ToObservable()
                .Select(x => new
                {
                    Value = x,
                    Seconds = sw.Elapsed.TotalSeconds
                })
                .Buffer(5, 1)
                .Where(xs => xs.Last().Seconds - xs.First().Seconds <= 1.0)
                .Subscribe(ks => Console.WriteLine($"More than five! {ks.Count}"));
        }

        public static IEnumerable<ConsoleKeyInfo> Keys()
        {
            while (true)
            {
                yield return Console.ReadKey(true);
            }
        }
    }
}
+3
source

If performance is not a problem, you can try this (not tested):

private float totalCount = 0f;
private float countOne = 1f;
private List<DateTime> pressedTime = new List<DateTime>();

void Update(){

    if(Input.GetKeyDown(KeyCode.F)){

        pressedTime.Add(DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
    }

    if (pressedTime.Count == 5){
        if ( (DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")) - pressedTime[0]).Seconds <= 1)
            do stuff
        pressedTime.Remove(0);
    }
}

EDIT: Queued

private float totalCount = 0f;
private float countOne = 1f;
private Queue<DateTime> myQ = new Queue<DateTime>();

void Update(){

    if(Input.GetKeyDown(KeyCode.F)){

        pressedTime.Enqueue(DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")));
    }

    if (pressedTime.Count == 5){
        if ( (DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")) - pressedTime.Peek()).Seconds <= 1)
            do stuff
        pressedTime.Dequeue();
    }
}
+2
source

System.Reactive Unity Unity, Time.realtimeSinceStartup, DateTime, :

public float interval = 1f;
public int count = 5;
private Queue<float> timeStamps = new Queue<float>();

void Update () {
    if (Input.GetKeyDown(KeyCode.F)) {
        float secsNow = Time.realtimeSinceStartup;
        timeStamps.Enqueue(secsNow);
        if (timeStamps.Count >= count) {
            float oldest = timeStamps.Dequeue();
            if (secsNow - oldest < interval) {
                Debug.Log("pressed " + count + " times in " + (secsNow - oldest) + "sec");
            }
        }
    }

}
0

Source: https://habr.com/ru/post/1691918/


All Articles