UnityのInputManagerで指定できるボタン名とKeyCodeの相互変換を試みます。
その前にいくらか前提を説明します。
Inputは設定が面倒
Unityでユーザの操作入力を取り扱うにはInputクラスを使います。
押しているかどうかboolで判断するButton系の取得と、どれぐらいの強さで入力されているか[-1, 1]範囲のfloatを返すAxis系があります。
ここで入力値を得るために指定する名前は、入力設定(InputManager)で設定した仮想軸の名前になります。デフォルトではHorizontal、Vertical、Fire1、Fire2、Fire3、Jump、Submit、Cancelなどが設定されているはずです。定義した仮想軸はButtonとしてもAxisとしても使用できます。良い感じに補間するための設定がInputManagerにあります。
任意の名前をつけた仮想軸を定義できるのは良いのですが、ゲーム中に設定を差し替えることができなかったり、割り当てるボタンを指定するフォーマットに統一性がなかったりと、そのまま使おうとするのは無理があると思います。どうしてこうなった。
Inputにラッパーかぶせるとかするにしても、InputManagerの設定は無視できないところです。しかし、**InputManagerをスクリプトから操作するAPIが公開されていません。**うわぁ、めんどくせぇ。
とはいえ、これを手で設定するのはあり得ないでしょう。
どうせYAMLで書き出せばテキスト処理でどうとでもなると思い、昔はYAMLを書き出すスクリプトを書いたこともありましたが、もっと良い方法がありました。
上の記事では、SerializedPropertyを通してInputManager.assetを編集する試みをしています。フォーマットがYAMLかどうかにも依存しないし、一番まともっぽいアプローチ。
ただ、割り当てるボタンを文字列で指定するところが面倒です。これ結局KeyCodeを指定することと同義なのですが、ドロップダウンリストで指定するわけでもなく、独自フォーマットの名前を直接入力しないといけません。
ボタン名の大まかなルールは上記ドキュメントにまとまっていますが、正しい名前を手で打ち込むのもバカらしいですし、そもそも正解がよくわかりません。
というわけで、前置きが長くなりましたが、KeyCodeとボタン名の相互変換を試みます。このボタン名は仮想軸の割り当てに使ってもらってもいいし、Input.GetKey()に直接指定しても使えます。後者の場合、普通にKeyCodeを指定する方が当然便利です。
InputManagerの自動生成については先に紹介した記事を参考にしてください。私はもう少し都合よく整理していますが、基礎は同じなので割愛。
実装
KeyCodeとして定義されたenumの名前変換テーブルを作ってやればOKです。
以前に書いたキャメルケースの分割を利用します(今回のために実装した副産物を別の記事にしただけ)。
public static class KeyCodeUtil
{
private static readonly Dictionary<KeyCode, string> specifiedNames = new Dictionary<KeyCode, string> {
{ KeyCode.Exclaim, "!" },
{ KeyCode.DoubleQuote, "\"" },
{ KeyCode.Hash, "#" },
{ KeyCode.Dollar, "$" },
{ KeyCode.Ampersand, "&" },
{ KeyCode.Quote, "'" },
{ KeyCode.LeftParen, "(" },
{ KeyCode.RightParen, ")" },
{ KeyCode.Asterisk, "*" },
{ KeyCode.Plus, "+" },
{ KeyCode.Comma, "," },
{ KeyCode.Minus, "-" },
{ KeyCode.Period, "." },
{ KeyCode.Slash, "/" },
{ KeyCode.Colon, ":" },
{ KeyCode.Semicolon, ";" },
{ KeyCode.Less, "<" },
{ KeyCode.Equals, "=" },
{ KeyCode.Greater, ">" },
{ KeyCode.Question, "?" },
{ KeyCode.At, "@" },
{ KeyCode.LeftBracket, "[" },
{ KeyCode.Backslash, "\\" },
{ KeyCode.RightBracket, "]" },
{ KeyCode.Caret, "^" },
{ KeyCode.Underscore, "_" },
{ KeyCode.BackQuote, "`" },
{ KeyCode.KeypadPeriod, "[.]" },
{ KeyCode.KeypadDivide, "[/]" },
{ KeyCode.KeypadMultiply, "[*]" },
{ KeyCode.KeypadMinus, "[-]" },
{ KeyCode.KeypadPlus, "[+]" },
{ KeyCode.KeypadEnter, "enter" },
{ KeyCode.KeypadEquals, "equals" },
{ KeyCode.Print, "print screen" },
};
private static readonly HashSet<string> ignoredNames = new HashSet<string> {
"LeftApple",
"RightApple",
};
private static readonly HashSet<KeyCode> ignoredCodes = new HashSet<KeyCode> {
KeyCode.None,
};
public static KeyCode toCode(string name)
{
KeyCode code;
if(_str2code.TryGetValue(name, out code)) {
return code;
}
return KeyCode.None;
}
public static string toName(this KeyCode code)
{
string name;
if(_code2str.TryGetValue(code, out name)) {
return name;
}
return "";
}
public static KeyCode mouse(int button)
{
if(button < 0 || button >= 7) return KeyCode.None;
var code = KeyCode.Mouse0 + button;
return code;
}
public static KeyCode joystick(int button)
{
if(button < 0 || button >= 20) return KeyCode.None;
var code = KeyCode.JoystickButton0 + button;
return code;
}
public static KeyCode joystick(int num, int button)
{
if(button < 0 || button >= 20) return KeyCode.None;
var code = KeyCode.None;
switch(num) {
case 1:
code = KeyCode.Joystick1Button0;
break;
case 2:
code = KeyCode.Joystick2Button0;
break;
case 3:
code = KeyCode.Joystick3Button0;
break;
case 4:
code = KeyCode.Joystick4Button0;
break;
default:
return KeyCode.None;
}
code += button;
return code;
}
static KeyCodeUtil()
{
foreach(var pair in specifiedNames) {
assign(pair.Key, pair.Value);
}
foreach(var name in Enum.GetNames(typeof(KeyCode))) {
assign(name);
}
}
private static void assign(string name)
{
if(ignoredNames.Contains(name)) return;
var code = (KeyCode)Enum.Parse(typeof(KeyCode), name);
if(ignoredCodes.Contains(code)) return;
if(_code2str.ContainsKey(code)) return;
var parts = splitName(name);
switch(parts[0]) {
case "alpha":
assign(code, parts[1]);
return;
case "f":
assign(code, name.ToLowerInvariant());
return;
case "keypad":
parts = parts.slice(1);
name = "[{0}]".format(string.Join(" ", parts.ToArray()));
assign(code, name);
return;
}
switch(parts.last()) {
case "arrow":
parts.RemoveAt(parts.Count - 1);
break;
case "control":
parts[parts.Count - 1] = "ctrl";
break;
case "command":
parts[parts.Count - 1] = "cmd";
break;
case "super":
parts[parts.Count - 1] = "super";
break;
}
assign(code, string.Join(" ", parts.ToArray()));
}
private static void assign(KeyCode code, string name)
{
_str2code[name] = code;
_code2str[code] = name;
}
private static List<string> splitName(string name)
{
var parts = name.splitCamelCase();
for(var i = 0; i < parts.Count; ++i) {
parts[i] = parts[i].ToLowerInvariant();
}
return parts;
}
private static readonly Dictionary<string, KeyCode> _str2code = new Dictionary<string, KeyCode>();
private static readonly Dictionary<KeyCode, string> _code2str = new Dictionary<KeyCode, string>();
}一応、ほぼすべてのKeyCodeが正しく指定できているか確認したつもりです。名前が不正だと、強制的に空欄にされるので、念のため確認してみてください。
=とequalsとか、どっちがキーパッドだよって感じですが、イコールキーの存在するキーボード持ってなかったので、動作確認はしていなくて、調査して出てきた結果を採用しています。キーパッドなら他と命名規則を統一して[equals]あるいは[=]のようにしてくれれば混乱しないのに。
Windowsキーはsuper系で名前がまとめられています。その名称をLinux文化に合わせるなら、KeyCodeの方もSuperにしておいてほしい・・・未定義なのかと思った・・・。
面倒なことにLeftApple、RightAppleはそれぞれLeftCommand、RightCommandと同じ値が割り当てられていて、区別不可能です(enumの内部表現は整数しか持ちません)。名前指定の存在するCommandキーとしてAppleキーをまとめるため、Enum.GetNames()からEnum.Parse()するという回りくどい対応になっています。そうしないとAppleキーの方で名前取得してしまうことがあるためです。良い子のみんなはenumの重複定義はやめようね。
対応表
せっかくなので、KeyCodeとボタン名の対応表も作りました。公式はこの表を用意してくれれば良かったんだ。
先にも述べたとおり、AppleキーはCommandキーと区別つかないので、同じボタン名が割り当てられています。
| KeyCode | ボタン名 |
|---|---|
| None | 未定義 |
| Backspace | backspace |
| Tab | tab |
| Clear | clear |
| Return | return |
| Pause | pause |
| Escape | escape |
| Space | space |
| Exclaim | ! |
| DoubleQuote | ” |
| Hash | # |
| Dollar | $ |
| Ampersand | & |
| Quote | ’ |
| LeftParen | ( |
| RightParen | ) |
| Asterisk | * |
| Plus | + |
| Comma | , |
| Minus | - |
| Period | . |
| Slash | / |
| Alpha0 | 0 |
| Alpha1 | 1 |
| Alpha2 | 2 |
| Alpha3 | 3 |
| Alpha4 | 4 |
| Alpha5 | 5 |
| Alpha6 | 6 |
| Alpha7 | 7 |
| Alpha8 | 8 |
| Alpha9 | 9 |
| Colon | : |
| Semicolon | ; |
| Less | < |
| Equals | = |
| Greater | > |
| Question | ? |
| At | @ |
| LeftBracket | [ |
| Backslash | \ |
| RightBracket | ] |
| Caret | ^ |
| Underscore | _ |
| BackQuote | ` |
| 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 |
| Delete | delete |
| Keypad0 | [0] |
| Keypad1 | [1] |
| Keypad2 | [2] |
| Keypad3 | [3] |
| Keypad4 | [4] |
| Keypad5 | [5] |
| Keypad6 | [6] |
| Keypad7 | [7] |
| Keypad8 | [8] |
| Keypad9 | [9] |
| KeypadPeriod | [.] |
| KeypadDivide | [/] |
| KeypadMultiply | [*] |
| KeypadMinus | [-] |
| KeypadPlus | [+] |
| KeypadEnter | enter |
| KeypadEquals | equals |
| UpArrow | up |
| DownArrow | down |
| RightArrow | right |
| LeftArrow | left |
| Insert | insert |
| Home | home |
| End | end |
| PageUp | page up |
| PageDown | page down |
| 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 | f13 |
| F14 | f14 |
| F15 | f15 |
| Numlock | numlock |
| CapsLock | caps lock |
| ScrollLock | scroll lock |
| RightShift | right shift |
| LeftShift | left shift |
| RightControl | right ctrl |
| LeftControl | left ctrl |
| RightAlt | right alt |
| LeftAlt | left alt |
| RightApple | right cmd |
| RightCommand | right cmd |
| LeftCommand | left cmd |
| LeftApple | left cmd |
| LeftWindows | left super |
| RightWindows | right super |
| AltGr | alt gr |
| Help | help |
| print screen | |
| SysReq | sys req |
| Break | break |
| Menu | menu |
| Mouse0 | mouse 0 |
| Mouse1 | mouse 1 |
| Mouse2 | mouse 2 |
| Mouse3 | mouse 3 |
| Mouse4 | mouse 4 |
| Mouse5 | mouse 5 |
| Mouse6 | mouse 6 |
| JoystickButton0 | joystick button 0 |
| JoystickButton1 | joystick button 1 |
| JoystickButton2 | joystick button 2 |
| JoystickButton3 | joystick button 3 |
| JoystickButton4 | joystick button 4 |
| JoystickButton5 | joystick button 5 |
| JoystickButton6 | joystick button 6 |
| JoystickButton7 | joystick button 7 |
| JoystickButton8 | joystick button 8 |
| JoystickButton9 | joystick button 9 |
| JoystickButton10 | joystick button 10 |
| JoystickButton11 | joystick button 11 |
| JoystickButton12 | joystick button 12 |
| JoystickButton13 | joystick button 13 |
| JoystickButton14 | joystick button 14 |
| JoystickButton15 | joystick button 15 |
| JoystickButton16 | joystick button 16 |
| JoystickButton17 | joystick button 17 |
| JoystickButton18 | joystick button 18 |
| JoystickButton19 | joystick button 19 |
| Joystick1Button0 | joystick 1 button 0 |
| Joystick1Button1 | joystick 1 button 1 |
| Joystick1Button2 | joystick 1 button 2 |
| Joystick1Button3 | joystick 1 button 3 |
| Joystick1Button4 | joystick 1 button 4 |
| Joystick1Button5 | joystick 1 button 5 |
| Joystick1Button6 | joystick 1 button 6 |
| Joystick1Button7 | joystick 1 button 7 |
| Joystick1Button8 | joystick 1 button 8 |
| Joystick1Button9 | joystick 1 button 9 |
| Joystick1Button10 | joystick 1 button 10 |
| Joystick1Button11 | joystick 1 button 11 |
| Joystick1Button12 | joystick 1 button 12 |
| Joystick1Button13 | joystick 1 button 13 |
| Joystick1Button14 | joystick 1 button 14 |
| Joystick1Button15 | joystick 1 button 15 |
| Joystick1Button16 | joystick 1 button 16 |
| Joystick1Button17 | joystick 1 button 17 |
| Joystick1Button18 | joystick 1 button 18 |
| Joystick1Button19 | joystick 1 button 19 |
| Joystick2Button0 | joystick 2 button 0 |
| Joystick2Button1 | joystick 2 button 1 |
| Joystick2Button2 | joystick 2 button 2 |
| Joystick2Button3 | joystick 2 button 3 |
| Joystick2Button4 | joystick 2 button 4 |
| Joystick2Button5 | joystick 2 button 5 |
| Joystick2Button6 | joystick 2 button 6 |
| Joystick2Button7 | joystick 2 button 7 |
| Joystick2Button8 | joystick 2 button 8 |
| Joystick2Button9 | joystick 2 button 9 |
| Joystick2Button10 | joystick 2 button 10 |
| Joystick2Button11 | joystick 2 button 11 |
| Joystick2Button12 | joystick 2 button 12 |
| Joystick2Button13 | joystick 2 button 13 |
| Joystick2Button14 | joystick 2 button 14 |
| Joystick2Button15 | joystick 2 button 15 |
| Joystick2Button16 | joystick 2 button 16 |
| Joystick2Button17 | joystick 2 button 17 |
| Joystick2Button18 | joystick 2 button 18 |
| Joystick2Button19 | joystick 2 button 19 |
| Joystick3Button0 | joystick 3 button 0 |
| Joystick3Button1 | joystick 3 button 1 |
| Joystick3Button2 | joystick 3 button 2 |
| Joystick3Button3 | joystick 3 button 3 |
| Joystick3Button4 | joystick 3 button 4 |
| Joystick3Button5 | joystick 3 button 5 |
| Joystick3Button6 | joystick 3 button 6 |
| Joystick3Button7 | joystick 3 button 7 |
| Joystick3Button8 | joystick 3 button 8 |
| Joystick3Button9 | joystick 3 button 9 |
| Joystick3Button10 | joystick 3 button 10 |
| Joystick3Button11 | joystick 3 button 11 |
| Joystick3Button12 | joystick 3 button 12 |
| Joystick3Button13 | joystick 3 button 13 |
| Joystick3Button14 | joystick 3 button 14 |
| Joystick3Button15 | joystick 3 button 15 |
| Joystick3Button16 | joystick 3 button 16 |
| Joystick3Button17 | joystick 3 button 17 |
| Joystick3Button18 | joystick 3 button 18 |
| Joystick3Button19 | joystick 3 button 19 |
| Joystick4Button0 | joystick 4 button 0 |
| Joystick4Button1 | joystick 4 button 1 |
| Joystick4Button2 | joystick 4 button 2 |
| Joystick4Button3 | joystick 4 button 3 |
| Joystick4Button4 | joystick 4 button 4 |
| Joystick4Button5 | joystick 4 button 5 |
| Joystick4Button6 | joystick 4 button 6 |
| Joystick4Button7 | joystick 4 button 7 |
| Joystick4Button8 | joystick 4 button 8 |
| Joystick4Button9 | joystick 4 button 9 |
| Joystick4Button10 | joystick 4 button 10 |
| Joystick4Button11 | joystick 4 button 11 |
| Joystick4Button12 | joystick 4 button 12 |
| Joystick4Button13 | joystick 4 button 13 |
| Joystick4Button14 | joystick 4 button 14 |
| Joystick4Button15 | joystick 4 button 15 |
| Joystick4Button16 | joystick 4 button 16 |
| Joystick4Button17 | joystick 4 button 17 |
| Joystick4Button18 | joystick 4 button 18 |
| Joystick4Button19 | joystick 4 button 19 |
| Joystick5Button0 | joystick 5 button 0 |
| Joystick5Button1 | joystick 5 button 1 |
| Joystick5Button2 | joystick 5 button 2 |
| Joystick5Button3 | joystick 5 button 3 |
| Joystick5Button4 | joystick 5 button 4 |
| Joystick5Button5 | joystick 5 button 5 |
| Joystick5Button6 | joystick 5 button 6 |
| Joystick5Button7 | joystick 5 button 7 |
| Joystick5Button8 | joystick 5 button 8 |
| Joystick5Button9 | joystick 5 button 9 |
| Joystick5Button10 | joystick 5 button 10 |
| Joystick5Button11 | joystick 5 button 11 |
| Joystick5Button12 | joystick 5 button 12 |
| Joystick5Button13 | joystick 5 button 13 |
| Joystick5Button14 | joystick 5 button 14 |
| Joystick5Button15 | joystick 5 button 15 |
| Joystick5Button16 | joystick 5 button 16 |
| Joystick5Button17 | joystick 5 button 17 |
| Joystick5Button18 | joystick 5 button 18 |
| Joystick5Button19 | joystick 5 button 19 |
| Joystick6Button0 | joystick 6 button 0 |
| Joystick6Button1 | joystick 6 button 1 |
| Joystick6Button2 | joystick 6 button 2 |
| Joystick6Button3 | joystick 6 button 3 |
| Joystick6Button4 | joystick 6 button 4 |
| Joystick6Button5 | joystick 6 button 5 |
| Joystick6Button6 | joystick 6 button 6 |
| Joystick6Button7 | joystick 6 button 7 |
| Joystick6Button8 | joystick 6 button 8 |
| Joystick6Button9 | joystick 6 button 9 |
| Joystick6Button10 | joystick 6 button 10 |
| Joystick6Button11 | joystick 6 button 11 |
| Joystick6Button12 | joystick 6 button 12 |
| Joystick6Button13 | joystick 6 button 13 |
| Joystick6Button14 | joystick 6 button 14 |
| Joystick6Button15 | joystick 6 button 15 |
| Joystick6Button16 | joystick 6 button 16 |
| Joystick6Button17 | joystick 6 button 17 |
| Joystick6Button18 | joystick 6 button 18 |
| Joystick6Button19 | joystick 6 button 19 |
| Joystick7Button0 | joystick 7 button 0 |
| Joystick7Button1 | joystick 7 button 1 |
| Joystick7Button2 | joystick 7 button 2 |
| Joystick7Button3 | joystick 7 button 3 |
| Joystick7Button4 | joystick 7 button 4 |
| Joystick7Button5 | joystick 7 button 5 |
| Joystick7Button6 | joystick 7 button 6 |
| Joystick7Button7 | joystick 7 button 7 |
| Joystick7Button8 | joystick 7 button 8 |
| Joystick7Button9 | joystick 7 button 9 |
| Joystick7Button10 | joystick 7 button 10 |
| Joystick7Button11 | joystick 7 button 11 |
| Joystick7Button12 | joystick 7 button 12 |
| Joystick7Button13 | joystick 7 button 13 |
| Joystick7Button14 | joystick 7 button 14 |
| Joystick7Button15 | joystick 7 button 15 |
| Joystick7Button16 | joystick 7 button 16 |
| Joystick7Button17 | joystick 7 button 17 |
| Joystick7Button18 | joystick 7 button 18 |
| Joystick7Button19 | joystick 7 button 19 |
| Joystick8Button0 | joystick 8 button 0 |
| Joystick8Button1 | joystick 8 button 1 |
| Joystick8Button2 | joystick 8 button 2 |
| Joystick8Button3 | joystick 8 button 3 |
| Joystick8Button4 | joystick 8 button 4 |
| Joystick8Button5 | joystick 8 button 5 |
| Joystick8Button6 | joystick 8 button 6 |
| Joystick8Button7 | joystick 8 button 7 |
| Joystick8Button8 | joystick 8 button 8 |
| Joystick8Button9 | joystick 8 button 9 |
| Joystick8Button10 | joystick 8 button 10 |
| Joystick8Button11 | joystick 8 button 11 |
| Joystick8Button12 | joystick 8 button 12 |
| Joystick8Button13 | joystick 8 button 13 |
| Joystick8Button14 | joystick 8 button 14 |
| Joystick8Button15 | joystick 8 button 15 |
| Joystick8Button16 | joystick 8 button 16 |
| Joystick8Button17 | joystick 8 button 17 |
| Joystick8Button18 | joystick 8 button 18 |
| Joystick8Button19 | joystick 8 button 19 |
上記リンク先は今回の変換処理をすべて配列で持つ実装をしたものですが、そこでの定義によると、KeyCodeに定義はなくても名前指定のできるものが存在します。廃止されたとかなんでしょうか。調べてもよくわかりませんでした。
world 0~world 95composepowereuroundo- Joystick 9~11系