2017-05-21 16 views
1

C#では、具体的にはUnity Scriptで、キー(ここではキーボード上の数字1、非キーパッド)が押されたかどうかを知るために次の行を使用できます最後のフレーム。 キーコードアルファを整数に変換するより効率的な方法

if (Input.GetKeyDown(KeyCode.Alpha1)) 
{ 
    MethodCall(1) 
} 

は今、私のゲームでは、私は、コール数が押されているに関係なく、まったく同じ方法たいと思いますが、パラメータとしてその番号を使用して、私は仕事をするすべての数字をしたいと思います。

if (Input.GetKeyDown(KeyCode.Alpha1)) 
{ 
    MethodCall(1) 
} 
if (Input.GetKeyDown(KeyCode.Alpha2)) 
{ 
    MethodCall(2) 
} 
if (Input.GetKeyDown(KeyCode.Alpha3)) 
{ 
    MethodCall(3) 
} 
// Etc 

をしかし、これは、この特定のユースケースを処理するひどく非効率的な方法のように思える:だからもちろん、私はこれを行うことができます。

私は単純にキーを自分のcharに変換してから文字列に変換し、それをintとして解析することを考えましたが、キーが少なくとも1つ数字。

答えが同じでない場合は、コード長と実行時間で最も効率的な方法は何でしょうか、この特定のタスクを実行するにはどうすればよいですか?

+0

内部に 'switch..case'ステートメントの長いセットを入れることができます。 – FortyTwo

答えて

1

Keycodeをキーに使用し、値として機能(Action)を使用します。 Start関数内のそれぞれのパラメータを持つ関数を追加します。これはifまたはswitchステートメントのすべてに乗ります。

Dictionary<KeyCode, System.Action> keyCodeDic = new Dictionary<KeyCode, System.Action>(); 

アルファKeycode列挙型は48から始まり、57で終了。 Start関数で

Alpha0 = 48, 
Alpha1 = 49, 
Alpha2 = 50, 
Alpha3 = 51, 
Alpha4 = 52, 
Alpha5 = 53, 
Alpha6 = 54, 
Alpha7 = 55, 
Alpha8 = 56, 
Alpha9 = 57, 

48から57のループはKeycodeにループから各int値をキャスト。各ループのをDictionaryに追加します。また、関数パラメータとして使用する一時変数を用意してください。この変数は0から始まり、各ループの後に増分されます。これは、キーボード上のアルファキーが0(Alpha0)から始まるので、0から開始する必要があります:Dictionaryを通じてUpdate機能ループで、

int paramValue = 0; 
for (int i = 48; i <= 57; i++) 
{ 
    KeyCode tempKeyCode = (KeyCode)i; 

    //Use temp variable to prevent it from being capture 
    int temParam = paramValue; 
    keyCodeDic.Add(tempKeyCode,() => MethodCall(temParam)); 
    paramValue++; 
} 

最後にして、押されてからのキーは、対応する関数を呼び出すかどうかを確認していますそのキーの値はDictionaryです。ここで

//Loop through the Dictionary and check if the Registered Keycode is pressed 
foreach (KeyValuePair<KeyCode, System.Action> entry in keyCodeDic) 
{ 
    //Check if the keycode is pressed 
    if (Input.GetKeyDown(entry.Key)) 
    { 
     //Check if the key pressed exist in the dictionary key 
     if (keyCodeDic.ContainsKey(entry.Key)) 
     { 
      //Debug.Log("Pressed" + entry.Key); 

      //Call the function stored in the Dictionary's value 
      keyCodeDic[entry.Key].Invoke(); 
     } 
    } 
} 

全体のことをどのように見えるかです:私は私の1,2または3またはNを返します方法 `int型GetKeyPressed(..)を作成します`

Dictionary<KeyCode, System.Action> keyCodeDic = new Dictionary<KeyCode, System.Action>(); 

void Start() 
{ 
    //Register Keycodes to to match each function to call 
    const int alphaStart = 48; 
    const int alphaEnd = 57; 

    int paramValue = 0; 
    for (int i = alphaStart; i <= alphaEnd; i++) 
    { 
     KeyCode tempKeyCode = (KeyCode)i; 

     //Use temp variable to prevent it from being capture 
     int temParam = paramValue; 
     keyCodeDic.Add(tempKeyCode,() => MethodCall(temParam)); 
     paramValue++; 
    } 
} 

void MethodCall(int keyNum) 
{ 
    Debug.Log("Pressed: " + keyNum); 
} 


void Update() 
{ 
    //Loop through the Dictionary and check if the Registered Keycode is pressed 
    foreach (KeyValuePair<KeyCode, System.Action> entry in keyCodeDic) 
    { 
     //Check if the keycode is pressed 
     if (Input.GetKeyDown(entry.Key)) 
     { 
      //Check if the key pressed exist in the dictionary key 
      if (keyCodeDic.ContainsKey(entry.Key)) 
      { 
       //Debug.Log("Pressed" + entry.Key); 

       //Call the function stored in the Dictionary's value 
       keyCodeDic[entry.Key].Invoke(); 
      } 
     } 
    } 
} 
+1

かなりきれいに見えますが、私の醜い方法に比べてパフォーマンスの低下は見られません。どうもありがとうございました! –

+1

TryGetValueはContainsよりも高速であると言われています。確認する。 – Everts

+0

そうです。私は 'keyCodeDic.ContainsKey'を残しておきました。もしOPがそれを拡張して' KeyCodes'を追加したいのであれば、簡単にデバッグできるようにしました。内部に 'Debug.Log(" Press "+ entry.Key")があります。 OPは 'keyCodeDicを置き換えることができます。すべてが設定されている場合は、 'TryGetValue'で' ContainsKey'とその中のすべてを調べます。 – Programmer

関連する問題