【Unity】【C#】InputSystem の Keyboard クラスと (旧)Input.GetKey の対応 
2020/10/05 Mon [edit]
InputSystem も Verified (正式版) となり、(旧)InputManager との混在も可能でもあるが、いずれ InputSystem の方法を中心として使いたいので調査中。
(旧)InputManager と InputSystem との対応は以下のマニュアルにも書かれているが、具体的に試してみた結果を書いておく。
(参考)Migrating from the old input system
今回は InputSystem.Keyboard クラスと、旧 Input.GetKey でのキー押下検出をフレーム単位での値で比較してみた。また、いつものように一覧表としてもまとめてみた。
●InputSystem 結果(一覧表)
■(旧)InputManager 版でのキーボード押下の遷移の値
●InputManager 結果(一覧表)
(※) Unity 2019.4.11f1 / InputSystem 1.0.0 / Windows10(x64) で確認
■InputSystem 版でのキーボード押下の遷移の値
●試したコード InputSystem 版
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
public class InputSystemKeyTest : MonoBehaviour
{
#if ENABLE_INPUT_SYSTEM
public Key inputSystemKey; //インスペクタで "None" 以外にする
//※ただし、Keyboard.current[Key.IMESelected] すると、なぜか ArgumentOutOfRangeException: Specified argument was out of the range of valid values. が出るので注意
bool pressing; //押下中フラグ
private void Update()
{
if (!pressing && Keyboard.current[inputSystemKey].wasPressedThisFrame) //押した
{
pressing = true;
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].wasPressedThisFrame = {Keyboard.current[inputSystemKey].wasPressedThisFrame}"); //True
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].isPressed = {Keyboard.current[inputSystemKey].isPressed}"); //True
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].wasReleasedThisFrame = {Keyboard.current[inputSystemKey].wasReleasedThisFrame}"); //False
}
else if (pressing && Keyboard.current[inputSystemKey].wasReleasedThisFrame) //離した
{
pressing = false;
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].wasPressedThisFrame = {Keyboard.current[inputSystemKey].wasPressedThisFrame}"); //False
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].isPressed = {Keyboard.current[inputSystemKey].isPressed}"); //False
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].wasReleasedThisFrame = {Keyboard.current[inputSystemKey].wasReleasedThisFrame}"); //True
}
else if (pressing) //継続中
{
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].wasPressedThisFrame = {Keyboard.current[inputSystemKey].wasPressedThisFrame}"); //False
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].isPressed = {Keyboard.current[inputSystemKey].isPressed}"); //True
Debug.Log($"frame: {Time.frameCount}, [{inputSystemKey}].wasReleasedThisFrame = {Keyboard.current[inputSystemKey].wasReleasedThisFrame}"); //False
}
else
{
//押してないとき
}
}
#endif
}
簡単に説明すれば、キーボードを押下したときのイベント(押した瞬間 → 押してる間 → 離した瞬間)の1フレーム内で、各関数・プロパティの値を比較したものだ。
●InputSystem 結果(一覧表)
押した | 継続中 | 離した | |
---|---|---|---|
Keyboard.current[Key].wasPressedThisFrame | True | False | False |
Keyboard.current[Key].isPressed | True | True | False |
Keyboard.current[Key].wasReleasedThisFrame | False | False | True |
Mouse の実験からも結果は予想通りであったが、これは後述する(旧)InputManager 結果とも一致する。どうやらキーボードを押下遷移の判定として完全に代替できそうだ。
ちなみにここでは、キーを InputSystem.Key (enum) を利用してるが、マニュアルにあるように、文字列やプロパティでも使えるようだ(ただし、文字列は型変換が必要)。
//Key(enum)型表記
Keyboard.current[Key.Escape].wasPressedThisFrame
//プロパティ表記
Keyboard.current.escapeKey.wasPressedThisFrame
//文字列型(※大文字小文字は区別しない)
((KeyControl)Keyboard.current["escape"]).wasPressedThisFrame //※要: KeyControl にキャスト
ただ、InputSystem.Key の整数値は、(旧)KeyCode とは一致してないので(文字列としても一部は一致してない:フルキー[0]~[9]や機能キー等)、旧システム互換を考えるなら、何ら変換する関数などあると便利かもね。
・InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの記号の Key 一覧
(InputSystem)
・Keyboard support
・Class Keyboard
・Class KeyControl
・Enum Key
■(旧)InputManager 版でのキーボード押下の遷移の値
●試したコード (旧)InputManager 版
using UnityEngine;
public class InputManagerKeyTest : MonoBehaviour
{
public KeyCode keyCode; //インスペクタで "None" 以外にする
bool pressing; //押下中フラグ
private void Update()
{
if (!pressing && Input.GetKeyDown(keyCode)) //押した
{
pressing = true;
Debug.Log($"frame: {Time.frameCount}, GetKeyDown = {Input.GetKeyDown(keyCode)}"); //True
Debug.Log($"frame: {Time.frameCount}, GetKey = {Input.GetKey(keyCode)}"); //True
Debug.Log($"frame: {Time.frameCount}, GetKeyUp = {Input.GetKeyUp(keyCode)}"); //False
}
else if (pressing && Input.GetKeyUp(keyCode)) //離した
{
pressing = false;
Debug.Log($"frame: {Time.frameCount}, GetKeyDown = {Input.GetKeyDown(keyCode)}"); //False
Debug.Log($"frame: {Time.frameCount}, GetKey = {Input.GetKey(keyCode)}"); //False
Debug.Log($"frame: {Time.frameCount}, GetKeyUp = {Input.GetKeyUp(keyCode)}"); //True
}
else if (pressing) //継続中
{
Debug.Log($"frame: {Time.frameCount}, GetKeyDown = {Input.GetKeyDown(keyCode)}"); //False
Debug.Log($"frame: {Time.frameCount}, GetKey = {Input.GetKey(keyCode)}"); //True
Debug.Log($"frame: {Time.frameCount}, GetKeyUp = {Input.GetKeyUp(keyCode)}"); //False
}
else
{
//押してないとき
}
}
}
●(旧)InputManager 結果(一覧表)
押した | 継続中 | 離した | |
---|---|---|---|
Input.GetKeyDown(keyCode) | True | False | False |
Input.GetKey(keyCode) | True | True | False |
Input.GetKeyUp(keyCode) | False | False | True |
これは前述したInputSystem の結果と一致する。
ただ、Input.GetKey~ 系の引数 KeyCode の整数値と InputSystem.Key の整数値は一致してないようだ。文字列としても、一部は一致してない(というか、KeyCode はマウスやジョイスティックも含むので、元々完全一致はできないが、他にはフルキーの[0]~[9]や機能キー等の名前が違う)。
・InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの記号の Key 一覧
まぁ、フレーム単位での挙動は Mouse も含めて、新旧同じようなので、使い方は難しくない。
マニュアルを見てると、「No corresponding API yet.」(まだ対応するものがない)というのがいくつもあるので、全て新旧一致できるわけではないようだが、よく使われる機能なら完全互換でいけそうなものも多いね。
ただ、今まで使っていた (旧)InputManager のコード(※主に Input) は全て書き換えないとならないので、大変な労力がいるのが難点。なので、しばらくは一部機能だけ使う感じになるだろう。
いずれ、スワイプ, ピンチ, 長押しなどのライブラリも InputSystem に対応しようと思っているが、ラッパー関数でも作らないと、旧新互換で作るのは骨が折れるね(笑)。
(関連記事)
【Unity】【C#】(旧)KeyCode と InputSystem.Key の対応
【Unity】【C#】InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧
【Unity】【C#】InputSystem で Android のバックキーの isPressed がなぜか一定時間で false になる?
【Unity】【C#】InputSystem の displayName や control path から Key (キーコード) を取得する
【Unity】【C#】InputSystem の Mouse クラスと (旧)Input.GetMouseButton の対応
【Unity】【C#】InputSystem でマウスのホイール(scroll)取得と (旧)Input との対応
【Unity】【C#】InputSystem.TouchPhase の IsActive(), IsEndedOrCanceled() [拡張メソッド] の具体値
【Unity】5ボタンマウスの KeyCode 図解
- 関連記事
トラックバック
トラックバックURL
→http://fantom1x.blog130.fc2.com/tb.php/367-1009458b
この記事にトラックバックする(FC2ブログユーザー)
| h o m e |