LoginSignup
2
1

More than 1 year has passed since last update.

【Unity】スペースキーでGameObjectのアクティブ状態をトグル(on/off)できるようにする【エディタ拡張】

Posted at

はじめに

前は GameObject のon/off切り替え用に QuickToggle を使ってHierarchy上に☑を表示してたのですが、「 GameObject を選択してスペースキーで切り替えできれば☑のUIいらないのでは?」と思ったので作ってみました。思いの外つまづきポイントが多かったのでメモ。

ちなみに

  • 非再生時も動作
  • Shortcut Managerからショートカットキーを変更可能
    • スペースキー以外でトグルできる
  • Git管理でチームメンバーと機能を共有可能

です。

TL;DR

  1. 適当なディレクトリを作る
    • Assets/Scripts/Editor/ToggleActiveStateShortcut とか
  2. ↑のディレクトリに ForInternalAccess.asmref を追加
    • 作り方は *.asmdef とほぼ同じ
    • Projectウィンドウ右クリック → CreateAssembly Definition Reference
  3. ForInternalAccess.asmrefAssembly DefinitionUnityEditor.UI を指定する
  4. ForInternalAccess.asmref と同じディレクトリに以下のスクリプトを追加する。
ToggleActiveStateShortcut.cs
#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

結果:
スクリーンショット 2021-09-21 20.36.29.png

解説

*.asmref ファイルについて

*.asmrefAssembly DefinitionUnityEditor.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 が割り当てられています。

スクリーンショット_2021-09-21_19_26_43.png

チームメンバーと共有しない場合はShortcut Managerからこのショートカットにスペースキーを割り当てればやりたいことは実現できます。コンフリクトする旨が表示されますが Create Conflict を選べばOK。

スクリーンショット 2021-09-21 19.31.33.png

ちなみに最初に載せたコードでは最終的にはUnityにもとからある Main Menu/GameObject/Toggle Active State を呼び出しています。

ShortcutAttribute, [Shortcut(..)] については「AnimationとTimelineが同じスペースキーでコンフリクトしないなら方法があるはずだ」と思ってTimelineのソースコード読んでたら見つけました。

[MenuItem(..)][Shortcut(..)] の違い

[MenuItem]

  • メニューに項目が追加される
  • ショートカットがグローバルに定義される
    • 他で同じキーが割り当てられてるとコンフリクトする

[Shortcut]

  • メニューに項目が追加されない
  • ショートカットがウィンドウのローカル内に定義される(たぶん)
    • 他のウィンドウで同じキーが割り当てられててもコンフリクトしない

余談

Shortcutsウィンドウの上のほうに表示されてるキーボードにもいろいろ機能があって、下のコマンドをキーボードにDrag&Dropでショートカットキーを設定できたりしてビビった。思ったより高機能。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1