Unityでキーボードの高速入力に対応する方法

はいどーもこんにちは人生詰んでるツミオです。
みなさんUnityでキーボードの入力使ってますか?
使ってない人もたぶん多いですよね。
なんたってスマホ全盛期ですから。

しかし僕は時代に逆行したいと思います。
ちゅーわけで今日はキーボードの高速入力に対応する方法をご紹介いたしましょう。

参考サイト:
unityでタイピングゲームを作った時の高速タイパー向け入力受付について
Super-fast input in Unity!

キーボードからの入力を受け取る方法

「キーボードの高速入力ってなんやねん」と思った方もいるかなと思います。
しかし比較のために、まずは通常のキーボードの入力に対応する方法を見てみましょう。

Unityではキー入力を受け取るとき、Inputクラスの機能を使うことが多いです。
Update関数内でInput.GetKeyメソッドをグルグル回してるサンプルコードはよく見かけますよね。
キーボード入力に対応しているゲームのほとんどはこの方法を取っているでしょう。

Update関数内でInputクラスを回す際に発生する問題

さて上述した「Update関数内でInput.GetKeyメソッドをグルグル回す方法」ですが、一つ問題点があります。
それはズバリ、高速入力に対応できないことです。
Update関数の実行頻度はフレームレートに依存しているため(たぶんね)、高速入力をおこなうと、押されたキーの取りこぼしが発生します。

高速入力とは何か

高速入力とは、一秒間に100キー以上の入力をおこなうことです。
「1秒間に100キーも押すはずないだろう」と思うかもしれませんが、瞬間的に100key/sec出すことも本当にないのでしょうか?

もしあなたの作っているゲームが「一秒間に100キーも押すはずがないし、仮に多少キーの取りこぼしがあったとしても無視できる」のであれば、Update関数内でInput.GetKeyメソッドをグルグル回す方法で何の問題もありません(例えばRPG)。
しかし「瞬間的に100key/sec出す可能性は十分にあり、押されたキーを取りこぼすことは絶対にあってはならない」のであれば(例えばタイピングゲーム)、Update関数内でInput.GetKeyメソッドをグルグル回す方法以外を検討すべきです。

取りこぼしを確認してみる

では実際に取りこぼしを確認してみましょう。
とはいえ一秒間に100キー以上打てたかどうかを確認するのは面倒ですので、もっと簡単に確認できるようにUnityの設定を変更します。
まず
Edit→Project Settings→Quality
を表示し、
OtherのV Sync CountをDon’t Syncにします。
その後、スクリプトを作成→空のオブジェクトにアタッチしたあと、スクリプトを以下のように変更します。

これでフレームレートが3に固定され、Aキーを押すと「A押されたよ」とコンソールに表示されるようになりました。

ゲームを実行し、Aキーを闇雲に連打してください。
実際にAキーを押した回数と、コンソール画面に表示されている「A押されたよ」の数が一致しないはずです。

次は

として試してみてください。
ほとんど取りこぼしが発生していないことがわかると思います。

普通はFPS3になんからないと思うかもしれませんが、「一時的に処理落ちした際にもきちんと入力を受け取りたい」といった場合、これは非常な問題となります。
また、何度か述べているように、処理落ちせずとも一秒間に100回ほど入力があると取りこぼしが発生します。

OnGUI関数でキー入力を受け取る

以上の問題を解決する方法は、ズバリOnGUI関数を利用することです。
OnGUI関数はフレームレートに依存しておらず、たとえFPSが3に落ちようとも全ての入力を適切に受け取ることが可能です。
具体的には以下のようなコードをOnGUI関数内で試してみてください。

きちんと入力した数のキーが表示されているはずです。

このOnGUI関数で受け取ったキーの一覧を保存しておき、Update関数が実行されたタイミングでその一覧を「実際に押されたこととして」シミュレートするのです。
もちろん、シミュレートしたあとはその一覧を空に戻します。
ちなみにですが、シフトキーが押されたかどうかはEvent.current.shiftで取得できます。

調べてみて

記事の最初にも参考サイトを挙げておきましたが、あらためて2つの参考サイトを紹介しておきます。
unityでタイピングゲームを作った時の高速タイパー向け入力受付について
Super-fast input in Unity!

これらのサイトがなければ、OnGUIを使うなんて発想は絶対に出てきませんでした。
ただこのOnGUIは「プレイヤーが操作する普通のゲーム内ユーザーインターフェイスに使う事は意図されていません」と書かれています。
実際のゲームで運用しても問題ないんでしょうかね。よくわかりません。
https://docs.unity3d.com/jp/540/Manual/GUIScriptingGuide.html
この辺は詳しい人にお任せしますw

Unityを始めてから二ヶ月程度が過ぎましたが、毎日新しい発見の連続です。
これからもUnityを遊び尽くしたいと思います。まる。

フォローする

『Unityでキーボードの高速入力に対応する方法』へのコメント

  1. 名前:いなはら 投稿日:2018/01/15(月) 16:49:30 ID:51d40f259

    突然の質問を失礼致します。
    Unityおよびプログラミング初心者のデザイナーです。

    『このOnGUI関数で受け取ったキーの一覧を保存しておき、Update関数が実行されたタイミングでその一覧を「実際に押されたこととして」シミュレートするのです。』

    のところで詰まってしまい、質問なのですが、
    受け取ったキーをどうやってどこに保存するのかが、検討がつかなくて困っています。

    具体的な方法のヒントなど教えてもらうことは可能でしょうか??

  2. 名前:いなはら 投稿日:2018/01/15(月) 16:49:54 ID:51d40f259

    突然の質問を失礼致します。
    Unityおよびプログラミング初心者のデザイナーです。

    『このOnGUI関数で受け取ったキーの一覧を保存しておき、Update関数が実行されたタイミングでその一覧を「実際に押されたこととして」シミュレートするのです。』

    のところで詰まってしまい、質問なのですが、
    受け取ったキーをどうやってどこに保存するのかが、検討がつかなくて困っています。

    具体的な方法のヒントなど教えてもらうことは可能でしょうか??

    • 名前:ツミオ 投稿日:2018/01/27(土) 13:51:10 ID:b6a1db4ff

      すみません、スパムとして処理されていたようです……。
      Twitterでやり取りした通りですので、恐らく解決済みかな? と思うのでここでの説明は省きますね(必要だったらまたおっしゃってください)。