- 2020/10/07 【Unity】【C#】(旧)KeyCode と InputSystem.Key の対応
- 2020/10/06 【Unity】【C#】InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧
- 2020/10/05 【Unity】【C#】InputSystem の Keyboard クラスと (旧)Input.GetKey の対応
- 2020/10/04 【Unity】【C#】InputSystem の Mouse クラスと (旧)Input.GetMouseButton の対応
- 2020/10/03 【Unity】【C#】InputSystem.TouchPhase の IsActive(), IsEndedOrCanceled() [拡張メソッド] の具体値
« prev next »
【Unity】【C#】(旧)KeyCode と InputSystem.Key の対応 
2020/10/07 Wed [edit]
InputSystem も Verified (正式版) となり、(旧)InputManager との混在も可能でもあるが、いずれ InputSystem の方法を中心として使いたいので調査中。
前回は InputSystem.Key と実際の(日本語)キーボードとの対応を調べたので、今回は (旧)InputManager の KeyCode との対応を調べてみた。
やり方は簡単で、以下の2つを同時にやれば良いだけだ。あくまで日本語キーボードでの調査であることに注意して欲しい。
・InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧
・KeyCode をリアルタイムで調べる / Windows 日本語キーボードでの記号の KeyCode 一覧
Unity 自体は海外製なので、実際には英語配列のキーボードで作られていると考えた方が良い。ここではその違いを一覧で見ておこうというわけだ。特に記号や機能キーの配置はキーボードによって違うので(104, 105, 106 キーボードとあるように)、ものによってはボタン自体がないという場合もある。使う時は確認してから実装しよう。
(※) Unity 2019.4.11f1 / InputSystem 1.0.0 / Windows10(x64) で確認
■(旧)KeyCode と InputSystem.Key の対応
マニュアルにも書いてあるが、キーは物理的な配置に依存しているらしいので、日本語配列と英語配列のキーボードでの違いに注意して欲しい。まぁ、Unity は海外製なので、基本的には英語配列キーボードを見て確かめた方が良いだろう。
(マニュアル日本語訳)
(参考
・キーボード。日本語配列と英語配列。
・101/104/109…キーボード配列、種類、構造についての解説と一覧
・キー配列
先に簡単なデータを述べておくと、現在のバージョン(掲載時点:Unity2019.4.11f1)では、KeyCode の名前の数は 全 326 個、InputSystem.Key の名前の数は 全 119 個である。
ここで「名前」と言っているのは、enum 型は int値での重複はできるので、値の方で数を調べてしまうと総数より少なくなってしまう可能性があるからである。また、enum の整数値は全く一致してない。
ただ、KeyCode の場合は、キーボードだけでなく、マウスやジョイスティックにも拡張されているので、今回の InputSystem.Key との照合の場合は余計なものも多い(InputSystem は Keyboard, Mouse, Touch に分かれている。ただし、Control paths のように文字列で指定することもできる)。
なので、その余計なもの(大まかには KeyCode.Mouse0 / .JoystickButton0 以降全て)を取り除くと、139 個となり、単純な名前一致は 79 個、不一致は 60 個となる。
そしてその不一致を眺めてみると、2つのパターンがある。
1. フルキー/テンキーを表す先頭文字列が変更されているもの (27 個)
・"Alpha0"(KeyCode) → "Digit0"(Key)
・"Keypad0"(KeyCode) → "Numpad0"(Key)
2. 単純に名前が変更されているもの (5 個)
・"Return"(KeyCode) → "Enter"(Key)
・"PrintScreen"(KeyCode) → "Print"(Key)
・"Menu"(KeyCode) → "ContextMenu"(Key)
・"LeftControl"(KeyCode) → "LeftCtrl"(Key)
・"RightControl"(KeyCode) → "RightCtrl"(Key)
これらを差し引くと、一致+一定パターン 111 個、不一致 28 個(計 139 個 [※Mouse0 以降は除外した数])となる。
また、Alt や Command キーは整数値が違ったり同じだったりするので、少しやっかいでもある。
ちなみに、"(なし)" となっているもののほとんどは、InputSystem.Key が物理的な配置キーに対し、KeyCode は文字ごとに値があるためだろう。
ただ、注意点として "Backslash" はどちらもあるのだが、InputSystem は物理配置に依存しているためか、日本語キーボードだと Key.Backslash (enum) では反応しないみたいだ。その代わり Key.OEM2 で反応した。この OEM~ はどうやら標準を 104 キーボードとし、105, 106,… のとき追加キーらしい。
しかし、ボタンの配置が変わってしまうと良くないので、他のやり方として、displayName を試してみたら、以下の表記で使えた。
//Backslash を displayName で使う
((KeyControl)Keyboard.current["#(\\\\)"]).wasPressedThisFrame //※要キャスト
//KeyboardLayout を利用
var keyControl = Keyboard.current.FindKeyOnCurrentKeyboardLayout("\\");
keyControl.wasPressedThisFrame //押した瞬間
他にも、記号系のキー "^", "@", "[", "]", :なども日本語キーボードだと位置が違うので注意が必要だ。これらも displayName から、前述の "Backslash" のように control path の方が良いかも知れない。
・Windows 日本語キーボードでの記号の InputSystem.Key 一覧
あと、まだバージョンが低いからか(掲載時点:InputSystem 1.0.0)、日本語変換キーや CapsLock キーを使うと InputSystem は不安定になる(?)ようだ(Keyboard.current.anyKey.~などが使えなくなったりする ← Unity公式にバグレポートとして出したが、「問題を確認できず」と返信が来た。もしかしたら、使っているキーボードによるのかも知れない:Windows日本語106キーボードとか、Shiftを押してCapsLockをするタイプのみとか、メーカーとか、ハードウェア依存がある?)。
まだしばらくは安定するまで、機能キーなど特殊なキーはなるべく避けた方が良いかも知れない。
●(旧)KeyCode と InputSystem.Key の対応 一覧表
(旧)KeyCode | InputSystem.Key | 備考 |
---|---|---|
None | None | |
Backspace | Backspace | |
Tab | Tab | |
Clear | (なし) | |
Return | Enter | |
Pause | Pause | |
Escape | Escape | |
Space | Space | |
Exclaim | (なし) | |
DoubleQuote | (なし) | |
Hash | (なし) | |
Dollar | (なし) | |
Percent | (なし) | |
Ampersand | (なし) | |
Quote | Quote | 日本語キーボードでは Key.Equals になる |
LeftParen | (なし) | |
RightParen | (なし) | |
Asterisk | (なし) | |
Plus | (なし) | |
Comma | Comma | |
Minus | Minus | |
Period | Period | |
Slash | Slash | |
Alpha0 | Digit0 | |
Alpha1 | Digit1 | |
Alpha2 | Digit2 | |
Alpha3 | Digit3 | |
Alpha4 | Digit4 | |
Alpha5 | Digit5 | |
Alpha6 | Digit6 | |
Alpha7 | Digit7 | |
Alpha8 | Digit8 | |
Alpha9 | Digit9 | |
Colon | (なし) | |
Semicolon | Semicolon | 日本語キーボードでは Key.Quote になる |
Less | (なし) | |
Equals | Equals | 日本語キーボードでは Key.Semicolon になる |
Greater | (なし) | |
Question | (なし) | |
At | (なし) | |
LeftBracket | LeftBracket | 日本語キーボードでは Key.RightBracket になる |
Backslash | Backslash | 日本語キーボードでは、KeyCode.Backslash で [\_] と [\|] キーが反応するが、InputSystem では InputSystem.Key.OEM2 で [\_] が反応する? |
RightBracket | RightBracket | 日本語キーボードでは Key.Backslash になる |
Caret | (なし) | |
Underscore | (なし) | |
BackQuote | Backquote | 日本語キーボードでは Key.LeftBracket になる |
A | A | |
B | B | |
C | C | |
D | D | |
E | E | |
F | F | |
G | G | |
H | H | |
I | I | |
J | J | |
K | K | |
L | L | |
M | M | |
N | N | |
O | O | |
P | P | |
Q | Q | |
R | R | |
S | S | |
T | T | |
U | U | |
V | V | |
W | W | |
X | X | |
Y | Y | |
Z | Z | |
LeftCurlyBracket | (なし) | |
Pipe | (なし) | |
RightCurlyBracket | (なし) | |
Tilde | (なし) | |
Delete | Delete | |
Keypad0 | Numpad0 | |
Keypad1 | Numpad1 | |
Keypad2 | Numpad2 | |
Keypad3 | Numpad3 | |
Keypad4 | Numpad4 | |
Keypad5 | Numpad5 | |
Keypad6 | Numpad6 | |
Keypad7 | Numpad7 | |
Keypad8 | Numpad8 | |
Keypad9 | Numpad9 | |
KeypadPeriod | NumpadPeriod | |
KeypadDivide | NumpadDivide | |
KeypadMultiply | NumpadMultiply | |
KeypadMinus | NumpadMinus | |
KeypadPlus | NumpadPlus | |
KeypadEnter | NumpadEnter | |
KeypadEquals | NumpadEquals | |
UpArrow | UpArrow | |
DownArrow | DownArrow | |
RightArrow | RightArrow | |
LeftArrow | LeftArrow | |
Insert | Insert | |
Home | Home | |
End | End | |
PageUp | PageUp | |
PageDown | PageDown | |
F1 | F1 | |
F2 | F2 | |
F3 | F3 | |
F4 | F4 | |
F5 | F5 | |
F6 | F6 | |
F7 | F7 | |
F8 | F8 | |
F9 | F9 | |
F10 | F10 | |
F11 | F11 | |
F12 | F12 | |
F13 | (なし) | |
F14 | (なし) | |
F15 | (なし) | |
Numlock | NumLock | |
CapsLock | CapsLock | |
ScrollLock | ScrollLock | |
RightShift | RightShift | |
LeftShift | LeftShift | |
RightControl | RightCtrl | |
LeftControl | LeftCtrl | |
RightAlt | RightAlt | ※AltGr 参照 |
LeftAlt | LeftAlt | |
RightCommand | RightCommand | KeyCode.RightCommand(309),.RightApple(309),.RightWindows(312)は整数値が一部異なるが、InputSystem.Key.RightCommand(58)と.RightApple(58),.RightWindows(58),.RightMeta(58)は同じ |
RightApple | RightApple | ※RightCommand 参照 |
LeftCommand | LeftCommand | KeyCode.LeftCommand(310),.LeftApple(310),.LeftWindows(311)は整数値が一部異なるが、InputSystem.Key.LeftCommand(57)と.LeftApple(57),.LeftWindows(57),.LeftMeta(57)は同じ |
LeftApple | LeftApple | ※LeftCommand 参照 |
LeftWindows | LeftWindows | ※LeftCommand 参照 |
RightWindows | RightWindows | ※RightCommand 参照 |
AltGr | AltGr | KeyCode.AltGr(313)と.RightAlt(307)は整数値が異なるが、InputSystem.Key.AltGr(54)と.RightAlt(54)は同じ |
Help | (なし) | |
PrintScreen | ※SysReq 参照 | |
SysReq | (なし) | 日本語キーボードだと [PrtScn] キーになる? |
Break | (なし) | |
Menu | ContextMenu |
マニュアルを見てると、「No corresponding API yet.」(まだ対応するものがない)というのがいくつもあるので、全て新旧一致できるわけではないようだが、よく使われる機能なら完全互換でいけそうなものも多いね。
ただ、今まで使っていた (旧)InputManager のコード(※主に Input) は全て書き換えないとならないので、大変な労力がいるのが難点。なので、しばらくは一部機能だけ使う感じになるだろう。
いずれ、スワイプ, ピンチ, 長押しなどのライブラリも InputSystem に対応しようと思っているが、ラッパー関数でも作らないと、旧新互換で作るのは骨が折れるね(笑)。
(関連記事)
【Unity】【C#】InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧
【Unity】【C#】KeyCode をリアルタイムで調べる / Windows 日本語キーボードでの記号の KeyCode 一覧
【Unity】【C#】InputSystem の Keyboard クラスと (旧)Input.GetKey の対応
【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 図解
【Unity】【C#】InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧 
2020/10/06 Tue [edit]
InputSystem も Verified (正式版) となり、(旧)InputManager との混在も可能でもあるが、いずれ InputSystem の方法を中心として使いたいので調査中。
これは以前に KeyCode でリアルタイムで調べるコードを InputSystem.Key に書き直したものだ。
ただ、システムの仕様なのかバグなのか、エラーが出たり挙動がおかしくなったりする場合があるのを確認している。参考程度で試して欲しい。
・KeyCode をリアルタイムで調べる / Windows 日本語キーボードでの記号の KeyCode 一覧
(※) Unity 2019.4.11f1 / InputSystem 1.0.0 / Windows10(x64) で確認
■InputSystem.Key をリアルタイムで調べるコード
●InputSystem.Key をリアルタイムで調べる
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
#endif
public class InputSystemRelatimeKeyCheck : MonoBehaviour
{
#if ENABLE_INPUT_SYSTEM
Key[] inputSystemKeys;
//Keyboard.current[key] で以下はエラーが出るため、除外するリスト
//ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
HashSet<Key> exceptKeys = new HashSet<Key>()
{
Key.None, Key.IMESelected,
};
private void Start()
{
inputSystemKeys = Enum.GetValues(typeof(Key))
.Cast<Key>()
.Where(e => !exceptKeys.Contains(e)) //exceptKeys にあるものは除く
.ToArray();
}
private void Update()
{
if (Keyboard.current.anyKey.wasPressedThisFrame) //Input.anyKeyDown 相当
{
foreach (var key in inputSystemKeys)
{
if (Keyboard.current[key].wasPressedThisFrame)
{
Debug.Log(key);
break;
}
}
}
}
#endif
}
コメントにも書いてあるが、Keyboard.current[key] では Key.None, Key.IMESelected を入れるとエラーを吐くようだ。もしかしたら、まだ他にもエラーになるものがあるかもと思い、HashSet で定義してあるが、今の所2つしかないようなので(掲載時点:1.0.0)、以下のように Where に直接書くのも良いだろう。
Key[] inputSystemKeys = Enum.GetValues(typeof(Key)).Cast<Key>().Where(e => e != Key.None && e != Key.IMESelected).ToArray();
あと、日本語変換キーや CapsLock キーを使うと(単体で CapsLock を押すとおかしくなる)、Keyboard.current.anyKey が利かなくなることがあるのも確認している(※キーボードによるかも? ← Unity公式にバグレポートとして出したが、「問題を確認できず」と返信が来た。もしかしたら、使っているキーボードによるのかも知れない:Windows日本語106キーボードとか、Shiftを押してCapsLockをするタイプのみとか、メーカーとか、ハードウェア依存がある?[掲載時点:1.0.0])。
■Windows 日本語キーボードでの InputSystem.Key 一覧
基本的には英語配列キーボードと照らし合わせて考えた方が良いだろう。特に記号や機能キーの配置は日本語配列キーボードでは違うので、使うなら注意した方が良いだろう。
(参考)
・キーボード。日本語配列と英語配列。
・101/104/109…キーボード配列、種類、構造についての解説と一覧
・キー配列
マニュアルにも書いてあるが、キーは物理的な配置に依存しているらしいので、日本語配列と英語配列のキーボードでの違いに注意して欲しい。まぁ、Unity は海外製なので、基本的には英語配列キーボードを見て確かめた方が良いだろう。私が調べてみた結果は後述の一覧にまとめた。
(マニュアル日本語訳)
ちなみに、Key (enum型) と displayName (文字列型) はコードでは以下のように使える。
//Key(enum)型表記
Keyboard.current[Key.A].wasPressedThisFrame
//displayName (文字列型) → control path にして利用(※大文字小文字は区別しない)
((KeyControl)Keyboard.current["#(a)"]).wasPressedThisFrame //※要: KeyControl にキャスト
//displayName (文字列型) を KeyboardLayout から検出
var keyControl = Keyboard.current.FindKeyOnCurrentKeyboardLayout("a");
keyControl.wasPressedThisFrame //押した瞬間
(マニュアル)Control paths
また、以下に displayName から簡単に Key (enum) を取得するメソッドも定義してみたので、コピペしておくと便利かも。
・displayName や control path から Key (キーコード) を取得する
●Windows 日本語キーボードでの記号の InputSystem.Key 一覧
InputSystem.Key (int) | (日本語)キーボード | displayName | 備考 |
---|---|---|---|
None (0) | (なし/未定義値) | (なし) | Keyboard.current[Key.None] とするとエラーになる |
Space (1) | Space | Space | |
Enter (2) | Enter | Enter | |
Tab (3) | Tab | Tab | |
Backquote (4) | 半角/全角 漢字 | 半角/全角 | |
Quote (5) | :* | : | |
Semicolon (6) | ;+ | ; | |
Comma (7) | ,< | , | |
Period (8) | .> | . | |
Slash (9) | /? | / | |
Backslash (10) | ]} | ] | |
LeftBracket (11) | @` | @ | |
RightBracket (12) | [{ | [ | |
Minus (13) | -= | - | |
Equals (14) | ^~ | ^ | |
A (15) | A | A | |
B (16) | B | B | |
C (17) | C | C | |
D (18) | D | D | |
E (19) | E | E | |
F (20) | F | F | |
G (21) | G | G | |
H (22) | H | H | |
I (23) | I | I | |
J (24) | J | J | |
K (25) | K | K | |
L (26) | L | L | |
M (27) | M | M | |
N (28) | N | N | |
O (29) | O | O | |
P (30) | P | P | |
Q (31) | Q | Q | |
R (32) | R | R | |
S (33) | S | S | |
T (34) | T | T | |
U (35) | U | U | |
V (36) | V | V | |
W (37) | W | W | |
X (38) | X | X | |
Y (39) | Y | Y | |
Z (40) | Z | Z | |
Digit1 (41) | フルキー 1 | 1 | |
Digit2 (42) | フルキー 2 | 2 | |
Digit3 (43) | フルキー 3 | 3 | |
Digit4 (44) | フルキー 4 | 4 | |
Digit5 (45) | フルキー 5 | 5 | |
Digit6 (46) | フルキー 6 | 6 | |
Digit7 (47) | フルキー 7 | 7 | |
Digit8 (48) | フルキー 8 | 8 | |
Digit9 (49) | フルキー 9 | 9 | |
Digit0 (50) | フルキー 0 | 0 | |
LeftShift (51) | 左 Shift | Shift | |
RightShift (52) | 右 Shift | Right Shift | |
LeftAlt (53) | 左 Alt | Alt | |
RightAlt (54) | 右 Alt | Right Alt | |
AltGr (54) | 右 Alt | Right Alt | RightAlt (54) と値重複(別名) |
LeftCtrl (55) | 左 Ctrl | Ctrl | |
RightCtrl (56) | 右 Ctrl | Right Control | |
LeftMeta (57) | Windowsキー | Left Windows | |
LeftWindows (57) | Windowsキー | Left Windows | LeftMeta (57) と値重複(別名) |
LeftCommand (57) | Windowsキー | Left Windows | LeftMeta (57) と値重複(別名) |
LeftApple (57) | Windowsキー | Left Windows | LeftMeta (57) と値重複(別名) |
RightCommand (58) | 右 Windowsキー(※未確認) | Right Windows | 英語キーボードでの場合。日本語キーボードの変換キー等は反応しない |
RightMeta (58) | 右 Windowsキー(※未確認) | Right Windows | RightCommand (58) と値重複(別名) |
RightWindows (58) | 右 Windowsキー(※未確認) | Right Windows | RightCommand (58) と値重複(別名) |
RightApple (58) | 右 Windowsキー(※未確認) | Right Windows | RightCommand (58) と値重複(別名) |
ContextMenu (59) | メニューキー | Application | |
Escape (60) | Esc | Esc | |
LeftArrow (61) | ← | Left | |
RightArrow (62) | → | Right | |
UpArrow (63) | ↑ | Up | |
DownArrow (64) | ↓ | Down | |
Backspace (65) | Backspace | Backspace | |
PageDown (66) | PgDn | Page Down | |
PageUp (67) | PgUp | Page Up | |
Home (68) | Home | Home | |
End (69) | End | End | |
Insert (70) | Insert | Insert | |
Delete (71) | Delete | Delete | |
CapsLock (72) | CapsLock | Caps Lock | CapsLockを使うとおかしくなることがある(※キーボードによるかも?) [※InputSystem 1.0.0 時点] |
NumLock (73) | NumLock | Pause | |
PrintScreen (74) | Print Screen | ||
ScrollLock (75) | ScrollLock | Scroll Lock | |
Pause (76) | Pause | Break | |
NumpadEnter (77) | テンキー Enter | Num Enter | |
NumpadDivide (78) | テンキー / | Num / | |
NumpadMultiply (79) | テンキー * | Num * | |
NumpadPlus (80) | テンキー + | Num + | |
NumpadMinus (81) | テンキー - | Num - | |
NumpadPeriod (82) | テンキー . | Num Del | |
NumpadEquals (83) | (未確認) | Numpad = | |
Numpad0 (84) | テンキー 0 | Num 0 | |
Numpad1 (85) | テンキー 1 | Num 1 | |
Numpad2 (86) | テンキー 2 | Num 2 | |
Numpad3 (87) | テンキー 3 | Num 3 | |
Numpad4 (88) | テンキー 4 | Num 4 | |
Numpad5 (89) | テンキー 5 | Num 5 | |
Numpad6 (90) | テンキー 6 | Num 6 | |
Numpad7 (91) | テンキー 7 | Num 7 | |
Numpad8 (92) | テンキー 8 | Num 8 | |
Numpad9 (93) | テンキー 9 | Num 9 | |
F1 (94) | F1 | F1 | |
F2 (95) | F2 | F2 | |
F3 (96) | F3 | F3 | |
F4 (97) | F4 | F4 | |
F5 (98) | F5 | F5 | |
F6 (99) | F6 | F6 | |
F7 (100) | F7 | F7 | |
F8 (101) | F8 | F8 | |
F9 (102) | F9 | F9 | |
F10 (103) | F10 | F10 | |
F11 (104) | F11 | F11 | |
F12 (105) | F12 | F12 | |
OEM1 (106) | (不明) | OEM1 | ※OEM~ キーは追加キーらしい |
OEM2 (107) | \_ | \ | [\| ]キーは反応しない?(英語キーボードにはない) displayName で使うときは、((KeyControl)Keyboard.current["#(\\\\)"]).wasPressedThisFrame |
OEM3 (108) | (不明) | OEM3 | ※OEM~ キーは追加キーらしい |
OEM4 (109) | (不明) | OEM4 | ※OEM~ キーは追加キーらしい |
OEM5 (110) | (不明) | OEM5 | ※OEM~ キーは追加キーらしい |
IMESelected (111) | (なし) | (なし) | Keyboard.current[Key.IMESelected] とするとエラーになる |
マニュアルを見てると、「No corresponding API yet.」(まだ対応するものがない)というのがいくつもあるので、全て新旧一致できるわけではないようだが、よく使われる機能なら完全互換でいけそうなものも多いね。
ただ、今まで使っていた (旧)InputManager のコード(※主に Input) は全て書き換えないとならないので、大変な労力がいるのが難点。なので、しばらくは一部機能だけ使う感じになるだろう。
いずれ、スワイプ, ピンチ, 長押しなどのライブラリも InputSystem に対応しようと思っているが、ラッパー関数でも作らないと、旧新互換で作るのは骨が折れるね(笑)。
(関連記事)
【Unity】【C#】KeyCode をリアルタイムで調べる / Windows 日本語キーボードでの記号の KeyCode 一覧
【Unity】【C#】(旧)KeyCode と InputSystem.Key の対応
【Unity】【C#】InputSystem の displayName や control path から Key (キーコード) を取得する
【Unity】【C#】InputSystem の Keyboard クラスと (旧)Input.GetKey の対応
【Unity】【C#】InputSystem で Android のバックキーの isPressed がなぜか一定時間で false になる?
【Unity】【C#】InputSystem の Mouse クラスと(旧)Input.GetMouseButton の対応
【Unity】【C#】InputSystem でマウスのホイール(scroll)取得と (旧)Input との対応
【Unity】【C#】InputSystem.TouchPhase の IsActive(), IsEndedOrCanceled() [拡張メソッド] の具体値
【Unity】5ボタンマウスの KeyCode 図解
【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 図解
【Unity】【C#】InputSystem の Mouse クラスと (旧)Input.GetMouseButton の対応 
2020/10/04 Sun [edit]
InputSystem も Verified (正式版) となり、(旧)InputManager との混在も可能でもあるが、いずれ InputSystem の方法を中心として使いたいので調査中。
(旧)InputManager と InputSystem との対応は以下のマニュアルにも書かれているが、具体的に試してみた結果を書いておこう。
(参考)Migrating from the old input system
今回は InputSystem.Mouse クラスと、旧 Input.GetMouseButton でのクリック検出をフレーム単位での値で比較してみた。また、いつものように一覧表としてもまとめてみた。
●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 InputSystemMouseTest : MonoBehaviour
{
#if ENABLE_INPUT_SYSTEM
bool pressing; //押下中フラグ
private void Update()
{
if (!pressing && Mouse.current.leftButton.wasPressedThisFrame) //押した
{
pressing = true;
Debug.Log($"frame: {Time.frameCount}, wasPressedThisFrame = {Mouse.current.leftButton.wasPressedThisFrame}"); //True
Debug.Log($"frame: {Time.frameCount}, isPressed = {Mouse.current.leftButton.isPressed}"); //True
Debug.Log($"frame: {Time.frameCount}, wasReleasedThisFrame = {Mouse.current.leftButton.wasReleasedThisFrame}"); //False
}
else if (pressing && Mouse.current.leftButton.wasReleasedThisFrame) //離した
{
pressing = false;
Debug.Log($"frame: {Time.frameCount}, wasPressedThisFrame = {Mouse.current.leftButton.wasPressedThisFrame}"); //False
Debug.Log($"frame: {Time.frameCount}, isPressed = {Mouse.current.leftButton.isPressed}"); //False
Debug.Log($"frame: {Time.frameCount}, wasReleasedThisFrame = {Mouse.current.leftButton.wasReleasedThisFrame}"); //True
}
else if (pressing) //継続中
{
Debug.Log($"frame: {Time.frameCount}, wasPressedThisFrame = {Mouse.current.leftButton.wasPressedThisFrame}"); //False
Debug.Log($"frame: {Time.frameCount}, isPressed = {Mouse.current.leftButton.isPressed}"); //True
Debug.Log($"frame: {Time.frameCount}, wasReleasedThisFrame = {Mouse.current.leftButton.wasReleasedThisFrame}"); //False
}
else
{
//押してないとき
}
}
#endif
}
簡単に説明すれば、マウスの左ボタンをクリックしたときのイベント(押した瞬間 → 押してる間 → 離した瞬間)の1フレーム内で、各関数・プロパティの値を比較したものだ。
●InputSystem 結果(一覧表)
押した | 継続中 | 離した | |
---|---|---|---|
Mouse.current.leftButton.wasPressedThisFrame | True | False | False |
Mouse.current.leftButton.isPressed | True | True | False |
Mouse.current.leftButton.wasReleasedThisFrame | False | False | True |
これは後述する(旧)InputManager 結果と一致する。どうやらマウスクリック遷移の判定として完全に代替できそうだ。
ちなみにここでは、左ボタン(leftButton)のみではあるが、他のボタンなら Mouse.current.〇〇 を rightButton, middleButton, backButton, ForwardButton に変えれば良い。詳しくは公式マニュアルを見て欲しい。
・Mouse support (InputSystem)
また、前回調査したスマホなどのタッチの拡張メソッド(IsActive(), IsEndedOrCanceled())にも対応できそうだ。
■(旧)InputManager 版でのマウスクリック遷移の値
●試したコード (旧)InputManager 版(とりあえず、左クリックのみ)
using UnityEngine;
public class InputManagerMouseTest : MonoBehaviour
{
bool pressing; //押下中フラグ
private void Update()
{
if (!pressing && Input.GetMouseButtonDown(0)) //押した
{
pressing = true;
Debug.Log($"frame: {Time.frameCount}, GetMouseButtonDown = {Input.GetMouseButtonDown(0)}"); //True
Debug.Log($"frame: {Time.frameCount}, GetMouseButton = {Input.GetMouseButton(0)}"); //True
Debug.Log($"frame: {Time.frameCount}, GetMouseButtonUp = {Input.GetMouseButtonUp(0)}"); //False
}
else if (pressing && Input.GetMouseButtonUp(0)) //離した
{
pressing = false;
Debug.Log($"frame: {Time.frameCount}, GetMouseButtonDown = {Input.GetMouseButtonDown(0)}"); //False
Debug.Log($"frame: {Time.frameCount}, GetMouseButton = {Input.GetMouseButton(0)}"); //False
Debug.Log($"frame: {Time.frameCount}, GetMouseButtonUp = {Input.GetMouseButtonUp(0)}"); //True
}
else if (pressing) //継続中
{
Debug.Log($"frame: {Time.frameCount}, GetMouseButtonDown = {Input.GetMouseButtonDown(0)}"); //False
Debug.Log($"frame: {Time.frameCount}, GetMouseButton = {Input.GetMouseButton(0)}"); //True
Debug.Log($"frame: {Time.frameCount}, GetMouseButtonUp = {Input.GetMouseButtonUp(0)}"); //False
}
else
{
//押してないとき
}
}
}
●(旧)InputManager 結果(一覧表)
押した | 継続中 | 離した | |
---|---|---|---|
Input.GetMouseButtonDown(0) | True | False | False |
Input.GetMouseButton(0) | True | True | False |
Input.GetMouseButtonUp(0) | False | False | True |
これは前述したInputSystem の結果と一致する。
ちなみに Input.GetMouseButton~ 系では、引数の int は 0: 左ボタン, 1: 右ボタン, 2: 中ボタン, 3:戻るボタン, 4:進むボタン となっているので、整数値 → ButtonControl (leftButton, rightButton, middleButton, backButton, ForwardButton) を返す拡張メソッドでも作れば、簡単に変換できそうだ(もしかして、別の書き方もあるかも知れないが…※まだ調査中)。
また、マウスのボタンは KeyCode でも取れるので、その辺りと比較してみるのも良い。以下に参考資料を載せておこう。
・5ボタンマウスの KeyCode 図解
マニュアルを見てると、「No corresponding API yet.」(まだ対応するAPIがない)というのがいくつもあるので、全て新旧一致できるわけではないようだが、よく使われる機能なら完全互換でいけそうなものも多いね。
ただ、今まで使っていた (旧)InputManager のコード(※主に Input) は全て書き換えないとならないので、大変な労力がいるのが難点。なので、しばらくは一部機能だけ使う感じになるだろう。
いずれ、スワイプ, ピンチ, 長押しなどのライブラリも InputSystem に対応しようと思っているが、ラッパー関数でも作らないと、旧新互換で作るのは骨が折れるね(笑)。
(関連記事)
【Unity】【C#】InputSystem でマウスのホイール(scroll)取得と (旧)Input との対応
【Unity】【C#】InputSystem.TouchPhase の IsActive(), IsEndedOrCanceled() [拡張メソッド] の具体値
【Unity】【C#】(旧)KeyCode と InputSystem.Key の対応
【Unity】【C#】InputSystem の displayName や control path から Key (キーコード) を取得する
【Unity】【C#】InputSystem の Keyboard クラスと (旧)Input.GetKey の対応
【Unity】【C#】InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧
【Unity】5ボタンマウスの KeyCode 図解
【Unity】【C#】InputSystem.TouchPhase の IsActive(), IsEndedOrCanceled() [拡張メソッド] の具体値 
2020/10/03 Sat [edit]
InputSystem も Verified (正式版) となり、(旧)InputManager との混在も可能でもあるが、いずれ InputSystem の方法を中心として使いたいので勉強中。
現在は (旧)InputManager と InputSystem との対応を調査中だが、まだマニュアルにも詳しく説明が載ってないものもあるので、具体的に試してみた結果を書いておこう。
今回は InputSystem.TouchPhase の拡張メソッド IsActive(), IsEndedOrCanceled() がどういうものかわからなかったので(Description に何も書いてない[※掲載時点])、試してみた(InputSystem.InputExtensions クラスにある)。また、一覧としてまとめておくと見やすい気がするので、ついでに作ってみた。
(※) Unity 2019.4.11f1 / InputSystem 1.0.0 / Windows10(x64) で確認
■IsActive(InputSystem.TouchPhase)
●試したコード
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;
#endif
#if ENABLE_INPUT_SYSTEM
Debug.Log("Began = " + TouchPhase.Began.IsActive()); //True
Debug.Log("Canceled = " + TouchPhase.Canceled.IsActive()); //False
Debug.Log("Ended = " + TouchPhase.Ended.IsActive()); //False
Debug.Log("Moved = " + TouchPhase.Moved.IsActive()); //True
Debug.Log("None = " + TouchPhase.None.IsActive()); //False
Debug.Log("Stationary = " + TouchPhase.Stationary.IsActive()); //True
#endif
●IsActive(InputSystem.TouchPhase) 結果
Began | True |
---|---|
Canceled | False |
Ended | False |
Moved | True |
None | False |
Stationary | True |
結果は Began, Moved, Stationary が True になった。要するにタッチして操作している状態のようだ。
(旧)InputManager と照らし合わせれば、Input.GetMouseButton() の代わりになりそう(※GetMouseButton~ はタッチも取れる)。開始も含むがタッチの継続判定として利用できそう。
■IsEndedOrCanceled(InputSystem.TouchPhase)
●試したコード
using UnityEngine;
#if ENABLE_INPUT_SYSTEM
using UnityEngine.InputSystem;
using TouchPhase = UnityEngine.InputSystem.TouchPhase;
#endif
#if ENABLE_INPUT_SYSTEM
Debug.Log("Began = " + TouchPhase.Began.IsEndedOrCanceled()); //False
Debug.Log("Canceled = " + TouchPhase.Canceled.IsEndedOrCanceled()); //True
Debug.Log("Ended = " + TouchPhase.Ended.IsEndedOrCanceled()); //True
Debug.Log("Moved = " + TouchPhase.Moved.IsEndedOrCanceled()); //False
Debug.Log("None = " + TouchPhase.None.IsEndedOrCanceled()); //False
Debug.Log("Stationary = " + TouchPhase.Stationary.IsEndedOrCanceled()); //False
#endif
●IsEndedOrCanceled(InputSystem.TouchPhase) 結果
Began | False |
---|---|
Canceled | True |
Ended | True |
Moved | False |
None | False |
Stationary | False |
結果はメソッド名のままだが、Canceled, Ended が True になった。おおよそ IsActive() の反転値と考えて良い。ただし、None だけは未定義値みたいなもので、常に False となるようだ。
(旧)InputManager と照らし合わせれば、Input.GetMouseButtonUp() に近い(※GetMouseButton~ はタッチも取れる)。Ended は指を離したとき、Canceled はアプリからフォーカスが外れたときなどになるようだ。タッチの終了判定として利用できそう。
まだちょっと試しただけだが、InputSystem は反応も良い気がするし、設定 UI も割とわかりやすい。
ただ、今まで使っていた (旧)InputManager のコード(※主に Input) は全て書き換えないとならないので、大変な労力がいるね。
いずれ、スワイプ, ピンチ, 長押しなどのライブラリも InputSystem に対応しようと思っているが、ラッパー関数でも作らないと、旧新互換で作るのは骨が折れそうだ(笑)。
(関連記事)
【Unity】【C#】InputSystem の Mouse クラスと (旧)Input.GetMouseButton の対応
【Unity】【C#】InputSystem でマウスのホイール(scroll)取得と (旧)Input との対応
【Unity】【C#】InputSystem の Keyboard クラスと (旧)Input.GetKey の対応
【Unity】【C#】(旧)KeyCode と InputSystem.Key の対応
【Unity】【C#】InputSystem.Key をリアルタイムで調べる / Windows 日本語キーボードでの Key 一覧
【Unity】【C#】InputSystem の displayName や control path から Key (キーコード) を取得する
【Unity】【C#】スワイプ(フリック)を判定、方向を取得してコールバックする
【Unity】【C#】ピンチ操作を取得してコールバックする
【Unity】【C#】長押し(ロングタップ)を取得してコールバックする