如果按钮" F"在一秒钟内按下5次,做一些事情。
怎么样?起初,我想过做这样的事情:
private float totalCount = 0f;
private float countOne = 1f;
void Update(){
if(Input.GetKeyDown(KeyCode.F)){
totalCount += countOne;
}
if (totalCount == 5){
// do some thing
}
}
但显然,这并不是我想要的。那么我该如何实现呢?协程?
答案 0 :(得分:3)
Rx是这样做的理想方式。您可以使用一秒钟的简单缓冲区。
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);
}
}
}
}
答案 1 :(得分:2)
如果表现不成问题,你可以试试这个(没有经过测试):
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);
}
}
编辑:有队列
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 :(得分:0)
我无法在Unity中获得System.Reactive应答工作,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");
}
}
}
}