teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

3

誤字の訂正

2020/10/21 01:46

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -133,7 +133,7 @@
133
133
  - `Input`による判定で`KeyCode.Backslash`が出てきた時にInput Systemによる追加判定を行う。
134
134
 
135
135
  という手が使えるかもしれません。`Input`単独で両方のキーを識別する手段がどうにも見つからず、Input Systemならどうかと思って見てみたところ、どうやらこちらはバックスラッシュキーで[oem2Key](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_oem2Key)が反応するようでした。
136
- ですが円記号キーでは無反応(どのキーコントロールにも反応がない?)ような挙動をしていましたので、Input System単独でも厳しいかもしれません。そこで両方を折衷してみました。
136
+ ですが円記号キーでは無反応(どのキーコントロールにも反応がない?)ような挙動をしていましたので、Input System単独でも厳しいかもしれません。そこで両方を折衷してみました。
137
137
 
138
138
  ```C#
139
139
  using System;

2

OnGUIを使わない方法を検討

2020/10/21 01:46

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -122,4 +122,64 @@
122
122
  }
123
123
  }
124
124
  }
125
+ ```
126
+
127
+ ##さらに追記
128
+
129
+ 他にも、`OnGUI`に頼らずそれぞれのキーを識別できそうな可能性として...
130
+
131
+ - パッケージマネージャーでInput Systemをインストールし、「Edit」→「Project Settings...」の「Player」→「Other Settings」→「Configulation」→「Active Input Handling*」を「Both」にして旧来の`Input`とInput Systemが同時に動作するようにしておく。
132
+ - 大部分のキーの識別は従来通り`Update`内などで`Input`を使って行う。
133
+ - `Input`による判定で`KeyCode.Backslash`が出てきた時にInput Systemによる追加判定を行う。
134
+
135
+ という手が使えるかもしれません。`Input`単独で両方のキーを識別する手段がどうにも見つからず、Input Systemならどうかと思って見てみたところ、どうやらこちらはバックスラッシュキーで[oem2Key](https://docs.unity3d.com/Packages/com.unity.inputsystem@1.0/api/UnityEngine.InputSystem.Keyboard.html#UnityEngine_InputSystem_Keyboard_oem2Key)が反応するようでした。
136
+ ですが円記号キーでは無反応(どのキーコントロールにも反応がない?)ような挙動をしていましたので、Input System単独でも厳しいかもしれません。そこで両方を折衷してみました。
137
+
138
+ ```C#
139
+ using System;
140
+ using System.Linq;
141
+ using UnityEngine;
142
+ using UnityEngine.InputSystem;
143
+
144
+ public class BackslashTest4 : MonoBehaviour
145
+ {
146
+ private readonly KeyCode[] keyCodes = Enum.GetValues(typeof(KeyCode)).Cast<KeyCode>().ToArray();
147
+
148
+ private void Update()
149
+ {
150
+ // 何らかのキーが押し下げられたら...
151
+ if (Input.anyKeyDown)
152
+ {
153
+ // すべてのキーを走査して...
154
+ foreach (var key in keyCodes)
155
+ {
156
+ // キーダウンがあったかを調べ...
157
+ if (Input.GetKeyDown(key))
158
+ {
159
+ if (key == KeyCode.Backslash)
160
+ {
161
+ // キーコードがBackslashの時は、さらにOEM2キーに反応があるかを調べる
162
+ if (Keyboard.current.oem2Key.wasPressedThisFrame)
163
+ {
164
+ // 反応があれば右シフト隣のバックスラッシュ
165
+ Debug.Log("Backslash");
166
+ }
167
+ else
168
+ {
169
+ // 反応がなければバックスペース隣の円記号
170
+ Debug.Log("Yen");
171
+ }
172
+ }
173
+ else
174
+ {
175
+ // バックスラッシュ以外はそのまま表示
176
+ Debug.Log(key);
177
+ }
178
+
179
+ break;
180
+ }
181
+ }
182
+ }
183
+ }
184
+ }
125
185
  ```

1

追加調査の結果を追記

2020/10/21 01:44

投稿

Bongo
Bongo

スコア10816

answer CHANGED
@@ -36,4 +36,90 @@
36
36
  }
37
37
  ```
38
38
 
39
- 私の場合は区別できたように見えたのですが、はたしてどの環境でも通用するのかはすごく不確かです。すみません...
39
+ 私の場合は区別できたように見えたのですが、はたしてどの環境でも通用するのかはすごく不確かです。すみません...
40
+
41
+ ##追記
42
+
43
+ 下記のようにもっと詳しい情報を出力させるようにしたバージョンを試してみたところ...
44
+
45
+ ```C#
46
+ using UnityEngine;
47
+
48
+ public class BackslashTest2 : MonoBehaviour
49
+ {
50
+ private bool needsCheckBackslash;
51
+
52
+ private void Update()
53
+ {
54
+ if (Input.GetKeyDown(KeyCode.Backslash))
55
+ {
56
+ this.needsCheckBackslash = true;
57
+ Debug.Log($"Update frame: {Time.frameCount}");
58
+ }
59
+ }
60
+
61
+ private void OnGUI()
62
+ {
63
+ if (this.needsCheckBackslash)
64
+ {
65
+ var e = Event.current;
66
+ Debug.Log($"OnGUI frame: {Time.frameCount}, Event type: {e.type}");
67
+ if (e.isKey)
68
+ {
69
+ if (e.functionKey)
70
+ {
71
+ Debug.Log("Backslash");
72
+ }
73
+ else
74
+ {
75
+ Debug.Log("Yen");
76
+ }
77
+
78
+ this.needsCheckBackslash = false;
79
+ }
80
+ }
81
+ }
82
+ }
83
+ ```
84
+
85
+ ご質問者さんのご指摘通り、`KeyDown`を見逃して`KeyUp`時点で反応していたようでした。
86
+
87
+ ![図](480e107603125fe08b85850034ca49be.png)
88
+
89
+ どうやら「`Update`でキーダウンがあったかを判断し、その後の`OnGUI`で円記号かバックスラッシュか判定する」というのでは遅すぎたようです。全部`OnGUI`内で完結させるよりないかもしれません。
90
+
91
+ ```C#
92
+ using UnityEngine;
93
+
94
+ public class BackslashTest3 : MonoBehaviour
95
+ {
96
+ private void OnGUI()
97
+ {
98
+ var e = Event.current;
99
+ if (e.type == EventType.KeyDown)
100
+ {
101
+ // https://docs.unity3d.com/ja/current/ScriptReference/EventType.KeyDown.html によると
102
+ // キーを押した時にはkeyCodeを持つイベントとcharacterを持つイベントが別々に発行されるらしい
103
+ if (e.keyCode == KeyCode.None)
104
+ {
105
+ Debug.Log($"Character: [{e.character}]");
106
+ }
107
+ else if (e.keyCode == KeyCode.Backslash)
108
+ {
109
+ if (e.functionKey)
110
+ {
111
+ Debug.Log("Backslash");
112
+ }
113
+ else
114
+ {
115
+ Debug.Log("Yen");
116
+ }
117
+ }
118
+ else
119
+ {
120
+ Debug.Log(e.keyCode);
121
+ }
122
+ }
123
+ }
124
+ }
125
+ ```