今回はUnityでキーボードから入力された文字が何だったか?という情報をスクリプトで判定する事をしていきたいと思います。
今回の記事ではInputManagerを使ってキーボードからの入力の判定をしますが、InputManagerではなく新しい入力システムであるInputSystemを使用する場合は以下の記事を参照してください。
Unityで入力デバイス(キーボードやマウス、ゲームパッド等)を使ってキャラクターを動かしたりステータス画面を表示したりといった事をしていますが、
スクリプトでこの入力デバイスからの入力を判断するのが、
Input.GetButtonDown(InputManagerで設定したボタンが押されたかどうかの取得)
Input.GetKeyDown(指定したキーが押されたかどうかの取得)
Input.GetMouseButtonDown(指定したマウスのボタンが押されたかどうかの取得)
といった関数になります。
上の例ではそれぞれ1度だけ押された時点で『押された!』という情報が取得出来ますが、それぞれに『押している間ずっと』、『押した後に離した時』といったタイミングで取得出来る関数があります。
Input.GetButtonの引数に指定するボタンの設定等に関しては
↑を参照してください。
今回はキーボードの入力について見ていきたいと思います。
他の関数でもタイミングについては同じなので関数名をそれに合わせて変更するだけです。
Input.GetKey等に指定する引数は?
Input.GetKey等の関数で指定する引数はキーボードのキーに対応する文字を渡すか、KeyCodeの列挙体を渡します。
例えば『左のShiftキーが押されている時』をスクリプトで記述する時は
1 2 3 4 5 6 7 8 9 10 11 12 13 | void Update () { // 左のシフトキーを文字列で判断 if(Input.GetKey("left shift")) { Debug.Log("LeftShiftChara"); } // 左のシフトキーをキーコードで判断 if(Input.GetKey(KeyCode.LeftShift)) { Debug.Log("LeftShiftKeyCode"); } } |
の二通りの判断が出来ます。
指定する引数の文字列は
↑で確認出来ます。
キーコードの種類は
↑で確認出来ます。
判断に利用するキーがわからなかったら上記のUnity公式マニュアルを見て頂くと載っています。
Input.GetKey等の戻り値は何?
Input.GetKey等の関数の戻り値は真偽値であるbool型の値(trueかfalse)が返ってきます。
戻り値って何!?って言う人もいるかもしれませんが・・・、戻り値は関数を実行した結果の最終的に得られる値ですね。
Input.GetKey等ではtrueかfalseという値が返ってくるのでif文といっしょに使い、引数で指定したキーが押されているかどうかを判断出来ます。
キーを検知する場所
キーボードのキーが押されているかどうかはUpdate関数内に記述します。
Update関数は毎フレーム呼ばれる関数なのでキーボードが押されているかどうかの判断に最適です。
Input.GetKey
Input.GetKeyは対応するキーボードのキーが押されている間ずっと呼ばれます。
FPSやTPSゲーム等の攻撃に対応するキーを押している間はずっとマシンガンを撃ちたい時に使用するといいと思います。
それではInput.GetKeyを実際に使ってみましょう。
『a』キーが押されている間はずっとコンソールに『a』という文字が表示されるようにしてみます。
1 2 3 4 5 6 7 8 9 10 11 | void Update () { // aキーを押している間ずっとコンソールに表示 if(Input.GetKey("a")) { Debug.Log("A-String"); } if(Input.GetKey(KeyCode.A)) { Debug.Log("A-KeyCode-"); } } |
正直なところ関数に渡す引数の所で挙げたサンプルと同じなので解説はいらないと思いますが・・・・(^_^;)
このスクリプトをヒエラルキー上のゲームオブジェクトにドラッグ&ドロップしてUnityを実行してaキーを押すと
↑のようにaキーを押している間はコンソールに文字列が表示されます。
離した時は実行されていません。
Input.GetKeyDown
Input.GetKeyDownはキーが押された時のフレームだけ判断されます。
その為キーをずっと押していても次のフレームでは押しているという判定がされません。
FPSやTPSで考えると普通の拳銃を撃つ場合はこのInput.GetKeyDownの方が向いていますね。
次に銃を撃つ時は一度キーを離してもう1度キーを押す必要があります。
それではEnterキーを押した時の例を見てみましょう。
1 2 3 4 5 6 7 8 9 10 11 | void Update () { if(Input.GetKeyDown("return")) { Debug.Log("Enter-String-"); } if(Input.GetKeyDown(KeyCode.Return)) { Debug.Log("Enter-KeyCode-"); } } |
Enterキーに対応する文字列は『enter』ではなく『return』みたいです。
今回はInput.GetKeyDownを使用していますのでEnterキーをずっと押していてもコンソールに表示されるのは1回だけです。
その後キーを離しまた押すと1回だけ判断され同じ状態が続きます。
Input.GetKeyUp
Input.GetKeyUp関数は対応するキーを一旦押した後、離した時に判定されます。
例えば石を投げるような動作をする時にキーを押した時に石を持って構えるアニメーションにしておき狙いを定めます。
狙いを定めた後にキーを離したらそこに石を投げる。
といった時にInput.GetKeyUpは使えると思います。
Spaceキーを押して離した時に文字列が表示されるようなスクリプトを作成してみます。
1 2 3 4 5 6 7 8 9 10 11 | void Update () { if(Input.GetKeyUp("space")) { Debug.Log("Space-String-"); } if(Input.GetKeyUp(KeyCode.Space)) { Debug.Log("Space-KeyCode-"); } } |
Unityの実行ボタンを押しSpaceキーを押して離してみましょう。
↑のように押した時は文字列は表示されず離した時に文字列が表示されています。
ボタンやマウスでのタイミングについて
今回はキーボードのキー入力限定で見ていきましたが、Input.GetButtonやInput.GetMouseButton等もDownやUpを変えて使用すると同じタイミングで実行されるのを確認出来ます。
引数に指定するものは
Intut.GetButton系はInputManagerで設定した名前(例えばFire1)
Input.GetMouseButton系はマウスのボタンに対応する番号(左ボタンは0、右ボタンは1、中ボタンは2が対応)
になっています。
Input.anyKeyとInput.anyKeyDown
特定のキーではなくキーボードのキーかマウスのボタンが押されているかだけを判断したい時もあると思います。
そんな時はInput.anyKey(押している間ずっと)とInput.anyKeyDown(押した時のフレーム1回だけ)を使用します。
これらはキーボードのキーだけでなくマウスのボタンを押した時にも反応するので注意が必要です。
それではサンプルスクリプトを使って確認してみましょう。
1 2 3 4 5 6 7 8 | void Update () { if(Input.anyKey) { Debug.Log("anyKey"); } } |
Input.anyKeyはキーボードのキー、マウスのボタンが押されている間ずっと実行されています。
1 2 3 4 5 6 7 8 | void Update () { if(Input.anyKeyDown) { Debug.Log("anyKeyDown"); } } |
Input.anyKeyDownはキーボードのキー、マウスのボタンが押された1回だけ実行されています。
特定のキーやマウスの検知が必要ない場合はこれらを使うと良さそうですね。
どのキーを押したか知りたい
ここまででは特定のキーが押されたかどうかのbool型の値を得ることは出来ましたが、実際に押したキーの取得は出来ていませんでした。
キーが押された時にDebug.Logで対応する文字を手動で記述し表示していただけです。
現在のフレームで押したキーが何だったかを知りたい時はInput.inputStringを使用します。
Input.inputStringは現フレーム内でキーボードで入力された文字列が入ります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | using UnityEngine; using System.Collections; public class InputStringTest : MonoBehaviour { void Update () { if(Input.anyKeyDown) { foreach(var c in Input.inputString) { // バックスペースキー if(c == "\b"[0]) { Debug.Log("BackSpace"); // EnterかReturn } else if(c == "\n"[0] || c == "\r"[0]) { Debug.Log("EnterOrReturn"); } else if(c == "\t"[0]) { Debug.Log("Tab"); // Spaceキーを取得( } else if(Input.GetKeyDown("space")) { Debug.Log("Space"); } else { // 空じゃなければ文字を表示 if(c.ToString () != "") { Debug.Log(c); } } } } } } |
↑のようにすれば押したキーが押されたフレーム内で表示されます。
Input.anyKeyDownの判定の後にInput.inputStringで押したキーを表示するのでBackSpaceやTab、Enter等のAscii文字以外のものは空白で表示されてしまいます。
その為の処理がInput.inputStringとエスケープ文字(\bはBackSpaceキーをあらわす)を使った判定をしている処理です。
エスケープ文字では空白文字が\sなんですが、うまく判定が出来なかったのでInput.GetKeyDown(“space”)で判定して個別に出力しています。
それ以外でInput.inputStringが空文字でなければコンソールにその文字を表示するようにしています。
またInput.inputStringで注意しなければいけないのはstring型の値ということです。
つまり同時にaとbを押した場合Input.inputStringの値はabになります。
その為Input.inputStringの値をそのまま使うのではなく繰り返し文を使ってInput.inputStringから1文字づつ取りだし判定を行っています。
Input.inputStringは小文字や大文字、数字と記号なども個別に取得出来ますがすべてのキーに対する対応が出来ていないと空文字が表示される可能性もある為注意が必要です。
終わりに
Input.GetButtonDown等を使ってInputManagerで設定したボタンに対応するキーやマウス、ゲームパッドのボタンを取得した方が色々なデバイスで操作するゲームを作成する時に便利です。
しかしキーボードをメインに使ったゲーム(タイピングゲーム)やゲームにキーボードを使ったショートカットキー操作を搭載したい場合はキーが直接押されているか判断した方が良い事もあります。
そういうものを作成する時に今回の実行されるタイミングを知っておくと役に立つかもしれませんね。