Reputation: 389
I'm wondering how to make it if, for example, button "F" being pressed 5 times within a second, do // something.
How though? At first, I thought about 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 isn't exactly what I want. So how do I achieve that? Coroutine?
Upvotes: 4
Views: 412
Reputation: 301
I could not get System.Reactive answer work in Unity and Unity has Time.realtimeSinceStartup that could be used instead of DateTime so I wrote one more example:
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");
}
}
}
}
Upvotes: 0
Reputation: 1481
If performance is not a problem, you could try this (haven't tested it):
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 : With queues
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();
}
}
Upvotes: 2
Reputation: 652
Rx is an ideal way of doing this. You can use a simple buffer of 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);
}
}
}
}
Upvotes: 3