2017-08-11 3 views
0

Je suis entrée et unité voulez faire jeu quiUnité double-clic (clavier) avec Time.deltaTime

avec TOURNER ↖ (7), ↗ (9) (besoin appuyant deux fois sur aussi)

DEPLACER avec ↑ ↓ ← → sur le pavé numérique 8,5,4,6 (double et aussi besoin de quelque chose comme ← ↑ → + Q)

.

J'ai besoin de détecter deux entrées comme ↗↗ à l'heure exacte et compter

mais parfois il a détecté deux fois, même si je double presse une seule fois ...

cela fait partie de mon script C#. (Src complète est inclus dans)

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 

Je pense qu'il est à cause de Time.deltaTime est diffrent pour tous les cadres.

Et un autre problème est survenu dans l'entrée de commande de mouvement (↑ ↓ ← →). (Je voudrais commencer par dash avec ↑↑) Il a parfois détecté deux fois même si je fais la source dans un style différent.

Si vous savez COMMENT CORRIGER CE PROBLÈME OU UNE MEILLEURE SOLUTION pour éviter tout problème, aidez-moi s'il vous plaît. (et je ne suis pas bon à l'anglais)

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

ce code est fait dans le style difrent. Utiliser l'histoire et ne pas utiliser deltaTime comme minimum timegap

mais le problème se produit similaire

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 
    } 
} 
+0

Toutes les actions requises fonctionnent bien, mais parfois "double détection" se produit – siamenock

+0

temps delta est "temps nécessaire pour procéder DERNIER CADRE pas cadre actuel" – siamenock

Répondre

2

Je ne sais pas, mais essayez Input.GetButtonDown au lieu de Input.GetButton.

Input.GetButton sera vrai tant que vous maintenez une touche enfoncée, cela peut donc être à l'origine de votre "double détection".

+0

OK .... il semble préférable d'utiliser Input.GetButtonDown – siamenock