使用Time.deltaTime双击Unity(键盘)

时间:2017-08-11 07:51:11

标签: c# unity3d input double unity5

我是Unity的首发,想要制作游戏

用↖(7),↗(9)旋转(也需要双击)

使用↑↓←→在小键盘8,5,4,6上移动(双倍并且还需要类似←↑→+ Q)

我需要在准确的时间和数量

检测double等双输入

但有时即使我只按一次就检测到两次......

这是我的C#脚本的一部分。 (完整的src包括在内)

void Update () {
    //get input
    is_r = Input.GetButton ("Keypad9");
    is_l = Input.GetButton ("Keypad7");
    is_rr= false;
    is_ll= false;

    if (is_r) {
        float gap = Time.time - time_r;
        if (Time.deltaTime + 0.05 < gap && gap < time_maxgap) {
                //seems like if Time.deltaTime change more than 0.05sec it works wrong
            is_rr = true;
            print ("deltatime = " + Time.deltaTime + "gap = " + gap);
        }
        time_r = Time.time;
    }
    // and more codes below

我认为这是因为Time.deltaTime对所有帧都不同。

并且运动(↑↓←→)命令输入也发生了similer问题。 (我想用↑↑开始冲刺)即使我以不同的风格制作源码,它有时会被检测到两次。

如果您知道如何修复此问题或更好的解决方案以避免问题,请帮助我。 (我不擅长英语)

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class CameraInputFilter : MonoBehaviour {
    float   time_maxgap = 0.3f;
    float   time_r = 0f,
            time_l = 0f;
    bool    is_r = false,
            is_l = false,
            is_rr= false,
            is_ll= false;

    // Use this for initialization
    void Start () {}

    // Update is called once per frame
    void Update () {
        //get input
        is_r = Input.GetButton ("Keypad9");
        is_l = Input.GetButton ("Keypad7");
        is_rr= false;
        is_ll= false;

        if (is_r) {
            float gap = Time.time - time_r;
            if (Time.deltaTime + 0.03 < gap && gap < time_maxgap) {
                is_rr = true;
                print ("deltatime = " + Time.deltaTime + "gap = " + gap);
            }
            time_r = Time.time;
        }
        if (is_l) {
            float gap = Time.time - time_l;
            if (Time.deltaTime + 0.01 < gap && gap < time_maxgap) {
                is_ll = true;
            }
            time_l = Time.time;
        }

        //send out result
        if (is_rr) {
            print ("rr");
        } else if (is_ll) {
            print ("ll");
        } else if (is_r && ! is_l){
            print ("r");
        } else if (is_l && ! is_r){
            print ("l");
        }
    }
}

此代码以不同的风格制作。 使用历史记录而不使用deltaTime作为最小时间差

但是发生了类似的问题

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


public class CommandFilter : MonoBehaviour {
    public GameObject obj;
    const float time_maxgap = 0.3f;
    //Key Code
    //todo : extract these codes into header file
    const int up    = 1;
    const int down  = 2;
    const int right = 3;
    const int left  = 4;
    const int sk1   = 5;
    const int sk2   = 6;
    const int sk3   = 7;
    const int signal= 8; //not a key input. used as counter & new_state signal

    //Keystate Code
    const int idle      = 0;
    const int on        = +1;
    const int on_new    = on * signal;
    const int off       = -1;
    const int off_new   = off * signal;

    //input for now, last (only 2 needed), input[0] not used.
    int[] input_new = new int[signal];
    int[] input_last= new int[signal];
    float time_deadline = 0f;


    //history of input summery(only 1 KEYSTATE CODE(int) saved)
    LinkedList<int> history = new LinkedList<int>();

    //Keystate summery
    //Usage : Keycode * Keystatecode
    //ex) history.Enque(up * on_new)
    //----------------------------------

    void Start () {
        HistoryInit ();
        input_last [up]     = off;  //these initializatiolns needs only once at start
        input_last [down]   = off;  //to make Compairing Last & New State works
        input_last [right]  = off;
        input_last [left]   = off;
        input_last [sk1]    = off;
        input_last [sk2]    = off;
        input_last [sk3]    = off;
    }



    void Update(){
        //save currunt key state
        input_new [up]      = Input.GetButton ("Keypad8")? on:off;
        input_new [down]    = Input.GetButton ("Keypad5")? on:off;
        input_new [right]   = Input.GetButton ("Keypad6")? on:off;
        input_new [left]    = Input.GetButton ("Keypad4")? on:off; //unexpected error : can't get 4 dirs at once. but not important now
        input_new [sk1]     = Input.GetButton ("Skill1") ? on:off;
        input_new [sk2]     = Input.GetButton ("Skill2") ? on:off;
        input_new [sk3]     = Input.GetButton ("Skill3") ? on:off;

        //print("input_current : " + input_new[up] + " " + input_new[down] + " " + input_new[right] + " " + input_new[left]);

        //mark new changes by compairing with last input (on -> on_new, off -> off_new)   and save currunt input
        bool no_change = true;
        for(int i = up; i < signal; i++){
            if (input_last [i] * input_new [i] < 0) {       //if button state changed (0 < on * on_new, same for off too)
                no_change = false;                          //report change
                input_last [i] = input_new [i] * signal;    //save change
                HistoryAdd(input_last[i] * i);              //save change
                //print("new input : " + input_last[i]);
            }
        }
        if (no_change && history.First != null && history.First.Value != idle) {
            HistoryAdd (idle);
        } else if ((no_change && time_deadline < Time.time)) {  //if input not change for more than command time gap(ex 0.3 sec)
            HistoryInit ();                                 //remove all history
        }


        string str = "";
        foreach (int i in history) {
            str += (i + " ");
        }
        int pattern = PatternSearch();
        if (pattern != 0) { 
            print ("pattern " + pattern /*+ " found\tcurrent history : " + str*/);
        } else {
            //print ("history : " + str);
        }
    }

    void HistoryInit(){
        time_deadline = Time.time + time_maxgap;
        history.Clear ();
        print ("HistoryInit");
    }
    void HistoryAdd(int summery_code){
        time_deadline = Time.time + time_maxgap;
        if (history.First != null && history.First.Value == idle) {
            history.RemoveFirst ();
        }
        history.AddFirst(summery_code);
    }

    int PatternSearch(){//hard corded patterns now. need to be reformed
        //Search pattern : evade front

        int[][] patterns = new int[][]{
            //todo2 : extract pattern list into other txt file
            //todo1 : make converter (string input -> int use)
            //ex) "34 checkoff U+ U- U+ U-" -> evade up, return 34
            //ex) "44 dontcare U+ U+"       -> dash  up, return 44, dont care keyoff
            new int[] {},   //0 not used
            new int[] { 0, on_new * left    ,on_new  * up   ,on_new  * right,on_new  * sk2  },  // multishot    (0 : not checkdown)
            new int[] { 1, on_new * up      ,off_new * up   ,on_new  * up   ,off_new * up   },  // evade        (1:checkdown)
            new int[] { 1, on_new * down    ,off_new * down ,on_new  * down ,off_new * down },  // evade        (1:checkdown)
            new int[] { 1, on_new * right   ,off_new * right,on_new  * right,off_new * right},  // evade        (1:checkdown)
            new int[] { 1, on_new * left    ,off_new * left ,on_new  * left ,off_new * left },  // evade        (1:checkdown)
            new int[] { 0, on_new * up      ,on_new  * up},                                     // start dash   (0 : not checkdown)
            new int[] { 0, on_new * down    ,on_new  * down},                                   // start dash   (0 : not checkdown)
            new int[] { 0, on_new * right   ,on_new  * right},                                  // start dash   (0 : not checkdown)
            new int[] { 0, on_new * left    ,on_new  * left},                                   // start dash   (0 : not checkdown)
            new int[] { 1, on_new * sk2     },                                                  // 평타
        };

        for(int i = 1; i <patterns.Length; i++){
            if (PatternMatch (patterns [i])) { return i;}
        }
        return 0;
    }

    bool PatternMatch(int [] pattern){
        bool checkdown = (pattern [0] == 1);
        LinkedListNode<int> it;
        int i = 0;

        //string str = "";
        for (i = pattern.Length - 1, it = history.First; it != null; i--, it = it.Next) {
            while(!checkdown && it.Value < 0){
                it = it.Next;
                if (it == null) {break;}
            }
            if (it == null) {break;}
            //str += pattern [i];
            if (pattern[i] != it.Value){
                break;
            }
            if (i == 1) {   //pattern[0] not used. it's just option
                return true;//pattern fully match
            }
        }
        return false;       //pattern not match
    }
}

1 个答案:

答案 0 :(得分:2)

不确定,但请尝试 Input.GetButton 而不是Input.GetButton

当你按下一个键时,

{{1}}将成立,这可能是你“双重检测”的原因。