はじめに
前は GameObject
のon/off切り替え用に QuickToggle を使ってHierarchy上に☑を表示してたのですが、「 GameObject
を選択してスペースキーで切り替えできれば☑のUIいらないのでは?」と思ったので作ってみました。思いの外つまづきポイントが多かったのでメモ。
ちなみに
- 非再生時も動作
- Shortcut Managerからショートカットキーを変更可能
- スペースキー以外でトグルできる
- Git管理でチームメンバーと機能を共有可能
です。
TL;DR
- 適当なディレクトリを作る
-
Assets/Scripts/Editor/ToggleActiveStateShortcut
とか
-
- ↑のディレクトリに
ForInternalAccess.asmref
を追加- 作り方は
*.asmdef
とほぼ同じ - Projectウィンドウ右クリック →
Create
→Assembly Definition Reference
- 作り方は
-
ForInternalAccess.asmref
のAssembly Definition
にUnityEditor.UI
を指定する -
ForInternalAccess.asmref
と同じディレクトリに以下のスクリプトを追加する。
#if UNITY_EDITOR
using UnityEditor;
using UnityEditor.ShortcutManagement;
using UnityEngine;
class ToggleActiveStateShortcut
{
[Shortcut("Hierarchy/Toggle Active State", typeof(SceneHierarchyWindow), KeyCode.Space)]
private static void ToggleActiveState()
{
EditorApplication.ExecuteMenuItem("GameObject/Toggle Active State");
}
}
#endif
解説
*.asmref
ファイルについて
*.asmref
の Assembly Definition
に UnityEditor.UI
を指定することでUnityの internal
クラスにアクセスできるようにします。これをやらないと typeof(SceneHierarchyWindow)
でコンパイルエラーになります。
*.asmref
について詳しくは以下の記事を参照のこと。
SceneHierarchyWindow
を参照できるなら *.asmref
を使わないやり方でもOK。
ShortcutAttribute
について
MenuItemAttribute
, [MenuItem(..)]
でいいのでは?
MenuItemAttribute
, [MenuItem(..)]
を使えばわざわざ internal
アクセスする必要がないのですが、試しに以下のスクリプトを配置してみると、
[MenuItem("Tools/Toggle Active State _SPACE")]
private static void ToggleActive()
{
// 処理
}
Animation/Play Animation
Timeline/Play
の2つとコンフリクトすることがわかります。
ちなみに [MenuItem]
でスペースキーを指定したい場合は
[MenuItem("Tools/FooBar _SPACE")]
みたいに _SPACE
を指定します。以下はどれもうまくいきません。
space
Space
SPACE
_space
_Space
最初これでやろうとしてググってもやり方がヒットしなくて苦労しました。
Main Menu/GameObject/Toggle Active State
でいいのでは?
もともとUnityには選択した GameObject
のオンオフを切り替えるショートカットがあり、Macだと option + shift + A
が割り当てられています。
チームメンバーと共有しない場合はShortcut Managerからこのショートカットにスペースキーを割り当てればやりたいことは実現できます。コンフリクトする旨が表示されますが Create Conflict
を選べばOK。
ちなみに最初に載せたコードでは最終的にはUnityにもとからある Main Menu/GameObject/Toggle Active State
を呼び出しています。
ShortcutAttribute
, [Shortcut(..)]
については「AnimationとTimelineが同じスペースキーでコンフリクトしないなら方法があるはずだ」と思ってTimelineのソースコード読んでたら見つけました。
- ShortcutAttribute(Unity公式リファレンス)
- 【Unity】エディタ拡張でショートカットキーから関数を呼び出せるようにする「ShortcutAttribute」(コガネブログ様)
[MenuItem(..)]
と [Shortcut(..)]
の違い
[MenuItem]
- メニューに項目が追加される
- ショートカットがグローバルに定義される
- 他で同じキーが割り当てられてるとコンフリクトする
[Shortcut]
- メニューに項目が追加されない
- ショートカットがウィンドウのローカル内に定義される(たぶん)
- 他のウィンドウで同じキーが割り当てられててもコンフリクトしない
余談
Shortcutsウィンドウの上のほうに表示されてるキーボードにもいろいろ機能があって、下のコマンドをキーボードにDrag&Dropでショートカットキーを設定できたりしてビビった。思ったより高機能。