はじめに
Unityのエディタ拡張にはMenuItemを使ってショートカットキーを登録する方法があります。
参考:http://baba-s.hatenablog.com/entry/2013/12/13/101637
この方法でだれでも手軽にショートカットキーを登録することができます。
[MenuItem("Custom/Pause _p")]
private static void Pause()
{
if(!EditorApplication.isPlaying)
{
return;
}
EditorApplication.isPaused = true;
}
例えば上記のようなコードがあったとすると、これは「p」を押すだけでプレイ中に一時停止することができます。
Unityの標準のままだと「Ctrl+Shift+P」を入力しないといけないのでとても楽になったのがわかります。
問題点
実は先ほどのコード、少し問題点があります。
それはEditor上での「p」入力を全て受け取ってしまい、GameObjectやファイルのリネーム時に「p」が入力できなくなってしまうことです。
そこでUnityのMenuItemリファレンスを見てみました。
https://docs.unity3d.com/jp/530/ScriptReference/MenuItem.html
この中の
[MenuItem("MyMenu/Log Selected Transform Name")]
static void LogSelectedTransformName()
{
Debug.Log("Selected Transform is on " + Selection.activeTransform.gameObject.name + ".");
}
[MenuItem("MyMenu/Log Selected Transform Name", true)]
static bool ValidateLogSelectedTransformName()
{
// Return false if no transform is selected.
return Selection.activeTransform != null;
}
この記述。
これはMenuItemの機能で、MenuItemの第二引数をtrueにしたValidateメソッドを用意してやることで、メニューを表示した際に実行可能かチェックするものです。
これを見る限り、現状の問題を解決してくれそうな気がしますが、残念ながらこれでは解決されません。
確かにメニューに表示した際は無効化され、メソッドは呼ばれなくなっていますが、しっかりとショートカットキー入力は受け取っているようです。
解決策
[MenuItem("Custom/Pause _p")]
private static void Pause()
{
if (!EditorApplication.isPlaying)
{
var window = EditorWindow.focusedWindow;
if (window != null)
{
window.SendEvent(Event.KeyboardEvent("p"));
}
return;
}
EditorApplication.isPaused = true;
}
ということで、MenuItemで指定したメソッドが呼ばれてしまうのは受け入れて、その中で新しくキーイベントを発光する方法をとりました。
var window = EditorWindow.focusedWindow;
if (window != null)
{
window.SendEvent(Event.KeyboardEvent("p"));
}
変更点はここです。
ここでは、まず現時点でフォーカスが当てられているWindowを取得します。
そのWindowに対して、KeyboardEventを発行してSendEventにて送っています。
こうすることによって、実際にはショートカットキーで呼ばれていますが、呼ばれていないように誤魔化すことができます。
まとめ
今回はショートカットキーを無効化にする方法を紹介しました。
ただ、この方法だと一部無効化しきれないこともあるので、ご注意ください。
ほかにいい方法があればお教えいただけると嬉しいです。
感想、意見などお待ちしております。
https://twitter.com/_ykringo