Type for layer selection

If I want to have layer-mask as member on my class I can use LayerMask type. But if I want to get single layer I have to use int and in that case I do not get nice dropdown-list of layers. Is there an easy way to define a member which would be displayed as a layer dropdown-list? Writing a custom Inspector doesn’t count as easy way.

There is a much simpler solution. Don’t create a custom class to store your value, but rather just create an attribute - then the entire process becomes WAY simpler than @Kyle_WG 's answer.

First: you need just an empty Attribute class.

/// <summary>
/// Attribute to select a single layer.
/// </summary>
public class LayerAttribute : PropertyAttribute
{ 
     // NOTHING - just oxygen.
}

And the PropertyDrawer (which becomes an editor for the attribute, instead of some excessive class to store value that shouldn’t need one.
This should go into your “Editor” scripts folder - or if you write assemblies instead - into your Whatever.Editor.dll assembly.

[CustomPropertyDrawer(typeof(LayerAttribute))]
class LayerAttributeEditor : PropertyDrawer
{
  
    public override void OnGUI(Rect position, SerializedProperty property, GUIContent label)
    {
        // One line of  oxygen free code.
         property.intValue = EditorGUI.LayerField(position, label,  property.intValue);
    }

}

So all you need to do to use it is the following (See Layer Attribute):

[SerializeField, Layer] int m_EditorLayer = 31;

And voila, you have a layer selection without gnarly code: 96741-dcs.png

An answer to an old post but I created a wrapper in C# for this issue cause I was tired of not being able to have one simple layer select or just using an integer.

For anyone else who stumbles on the message and issue. (heh) Always reminds me of this xkcd comic link text

Here’s the wrapper class:

using UnityEngine;

[System.Serializable]
public class SingleUnityLayer
{
    [SerializeField]
    private int m_LayerIndex = 0;
    public int LayerIndex
    {
        get { return m_LayerIndex; }
    }

    public void Set(int _layerIndex)
    {
        if (_layerIndex > 0 && _layerIndex < 32)
        {
            m_LayerIndex = _layerIndex;
        }
    }

    public int Mask
    {
        get { return 1 << m_LayerIndex; }
    }
}

And here’s the PropertyDrawer class. (Remember to throw it in a Editor folder in project.)

using UnityEditor;
using UnityEngine;

[CustomPropertyDrawer(typeof(SingleUnityLayer))]
public class SingleUnityLayerPropertyDrawer : PropertyDrawer 
{
    public override void OnGUI(Rect _position, SerializedProperty _property, GUIContent _label)
    {
        EditorGUI.BeginProperty(_position, GUIContent.none, _property);
        SerializedProperty layerIndex = _property.FindPropertyRelative("m_LayerIndex");
        _position = EditorGUI.PrefixLabel(_position, GUIUtility.GetControlID(FocusType.Passive), _label);
        if (layerIndex != null)
        {
            layerIndex.intValue = EditorGUI.LayerField(_position, layerIndex.intValue);
        }
        EditorGUI.EndProperty( );
    }
}

Just a bit more safer, because you can set the layer also in the source code:

using UnityEngine;
using System.Collections;
using System;
using UnityEditor;
     
[CustomPropertyDrawer(typeof(LayerAttribute))]
public class LayerAttributeEditor : PropertyDrawer {
	public override void OnGUI(Rect pos, SerializedProperty prop, GUIContent label) {
		EditorGUI.BeginProperty(pos, label, prop);
		int index = prop.intValue;
		if (index > 31) {
			Debug.Log("CustomPropertyDrawer, layer index is to high '" + index + "', is set to 31.");
			index = 31;
		} else if (index < 0) {
			Debug.Log("CustomPropertyDrawer, layer index is to low '" + index + "', is set to 0");
			index = 0;
		}
		prop.intValue = EditorGUI.LayerField(pos, label,  index);
		EditorGUI.EndProperty();
	}
}

public class LayerAttribute : PropertyAttribute { 
}