如果按钮在1秒内按下X次,请执行此操作吗?

时间:2018-01-09 10:54:31

标签: c# unity3d

如果按钮" 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
    }
}

但显然,这并不是我想要的。那么我该如何实现呢?协程?

3 个答案:

答案 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");
            }
        }
    }

}