🖱️

SceneView上での選択を無効にする

2022/08/10に公開

EditorToolをアクティブに保つ

問題の所在

EditorToolを継承したクラスを作るだけで簡単にエディタ上で使える独自ツールが作れます.

実際にエディタ上に表示するにはEditorToolAttributeを付けます.

特に制限なく使えるツールをグローバル・ツールと呼びます. この場合EditorToolAttributeはツールの名前だけを引数に取ります.

このツールはいつでもアクティブにできますが以下の点が面倒です.

  • 既存のツールバー上にまとめて追加されるため, ツールが増えると管理しずらい
  • アイコンはなくツールを拡張した感じがしない
GraphTool.cs
[EditorTool("Graph Tool")]
public class GraphTool : EditorTool {
}

EditorToolAttributeには第2引数があり, コンポーネントを指定できます. これをコンポーネント・ツールと呼び特定の選択中のオブジェクトがコンポーネントを持つ場合選択可能になります.

GraphTool.cs
[EditorTool("Graph Tool", typeof(Graph))]
public class GraphTool : EditorTool {
    // ...
}
Graph.cs
public class Graph : MonoBehaviour {
    // ...
}

下図で左端がコンポーネント・ツールでその右隣のドロップダウンが表示されているのがグローバル・ツールです.

コンポーネント・ツールの方がアイコンもあり, 対象となるコンポーネント付きゲームオブジェクトが選択されているときだけ自動でツールバーに表示されるので管理もしやすいです.

コンポーネント・ツール自体は便利なのですが, インタラクティブな操作をしようとするとオブジェクトが非選択になってしまいツールが自動的に無効になってしまいます.

シーン上で選択操作を無効にすることはできるでしょうか?

解決法

ProBuilderでもこのようなインタラクティブな操作は多用されます. そこでコードを見るとProBuilderEditor.csに以下のようなコメントがありました.

ProBuilderEditor.cs
// This prevents us from selecting other objects in the scene,
// and allows for the selection of faces / vertices.
m_DefaultControl = GUIUtility.GetControlID(FocusType.Passive);
if (Event.current.type == EventType.Layout)
    HandleUtility.AddDefaultControl(m_DefaultControl);

まさに求めていたものです.

まとめ

HandleUtility.AddDefaultControl(GUIUtility.GetControlID(FocusType.Passive));

Reference

ProBuilderを読んだ後にいろいろで調べたら以下のような質問もありました. 古くから知られた方法のようです.

Unity editor capture "hold mouse down and move" event

[SOLVED]: Custom Editor OnSceneGUI Scripting

Disable Mouse Selection in Editor View

How to disable selection other objects in scene view, (like edit-mode in LightProbeGroup inspector)

Discussion