レイヤーでフィルタリングできるSceneビューを作る


LayerBaseSceneView.cs
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Reflection;
using InternalEditorUtility = UnityEditorInternal.InternalEditorUtility;

public class LayerBaseSceneView : SceneView
{
    [MenuItem("Window/LayerBaseSceneView")]
    public static void Open ()
    {
        ScriptableObject.CreateInstance<LayerBaseSceneView> ().Show ();
    }

    private const int _AllLayerMask = 0xFFFF;
    private MethodInfo _internalOnGUI;
    private int _currentLayerMask;
    private int _selectedLayerMaskIndexies = 0xFFFF;

    public override void OnEnable ()
    {
        base.OnEnable ();
        // SceneView.OnGUIを取得する
        var type = typeof(SceneView);
        _internalOnGUI = type.GetMethod ("OnGUI", BindingFlags.Instance | BindingFlags.NonPublic);
    }

    ///
    public virtual void OnGUI ()
    {
        if (_internalOnGUI != null) {
            int visibleLayers = Tools.visibleLayers;
            // SceneViewに映るレイヤーを制限してから
            Tools.visibleLayers = _currentLayerMask;
            // 標準のSceneView.OnGUIを描く
            _internalOnGUI.Invoke (this, null);
            // レイヤーの制限を戻す
            Tools.visibleLayers = visibleLayers;
        }
        // ウィンドウの下の方に、LayerMaskを描く
        Rect pos = position;
        Rect maskRect = new Rect (){ width = pos.width - 20f, height = 20f, x = 0f, y = pos.height - 20f };
        string[] layers = InternalEditorUtility.layers;
        EditorGUI.DrawRect (new Rect (maskRect) {width = pos.width}, Color.black);
        int currentMaskIndexies = EditorGUI.MaskField (maskRect, "Visible Layer", _selectedLayerMaskIndexies, layers);
        if (currentMaskIndexies != _selectedLayerMaskIndexies) {
            _selectedLayerMaskIndexies = currentMaskIndexies;
            _currentLayerMask = 0;
            for (var i = 0; i < layers.Length; ++i) {
                int layerNumber = _selectedLayerMaskIndexies & (1 << i);
                if (layerNumber == 0) {
                    continue;
                }
                int mask = LayerMask.NameToLayer (layers [i]);
                _currentLayerMask |= (1 << mask);
            }
        }
    }
}