我是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
}
}
答案 0 :(得分:2)
不确定,但请尝试 Input.GetButton
而不是Input.GetButton
。
{{1}}将成立,这可能是你“双重检测”的原因。