- Home /
Mask field in the editor
How do i make a mask selection popup like the layer selection popup you get in the inspector for any LayerMask, except for my own mask object.
EnumPopup is almost right but does not allow multiple selection.
Answer by Eric5h5 · Apr 27, 2011 at 03:30 AM
var mask : LayerMask;
No I meant my own mask type. Layer$$anonymous$$ask will give me the layer options. I want my own custom options.
In that case I guess you'd have to write your own function for that.
That's disappointing as the functionality is already written for the layermask selection... oh well I guess I'll do this at some point.
Answer by TowerOfBricks · May 28, 2011 at 02:18 PM
I've written some code for this, unfortunately I cannot use the √ character to indicate a selected layer, I have to use [X] instead which looks a bit ugly. But it works. It does even support the Everything and Nothing selections (that's the 'showSpecial' flag).
public static LayerMask LayerMaskField (string label, LayerMask selected) {
return LayerMaskField (label,selected,true);
}
public static LayerMask LayerMaskField (string label, LayerMask selected, bool showSpecial) {
List<string> layers = new List<string>();
List<int> layerNumbers = new List<int>();
string selectedLayers = "";
for (int i=0;i<32;i++) {
string layerName = LayerMask.LayerToName (i);
if (layerName != "") {
if (selected == (selected | (1 << i))) {
if (selectedLayers == "") {
selectedLayers = layerName;
} else {
selectedLayers = "Mixed";
}
}
}
}
EventType lastEvent = Event.current.type;
if (Event.current.type != EventType.MouseDown && Event.current.type != EventType.ExecuteCommand) {
if (selected.value == 0) {
layers.Add ("Nothing");
} else if (selected.value == -1) {
layers.Add ("Everything");
} else {
layers.Add (selectedLayers);
}
layerNumbers.Add (-1);
}
if (showSpecial) {
layers.Add ((selected.value == 0 ? "[X] " : " ") + "Nothing");
layerNumbers.Add (-2);
layers.Add ((selected.value == -1 ? "[X] " : " ") + "Everything");
layerNumbers.Add (-3);
}
for (int i=0;i<32;i++) {
string layerName = LayerMask.LayerToName (i);
if (layerName != "") {
if (selected == (selected | (1 << i))) {
layers.Add ("[X] "+layerName);
} else {
layers.Add (" "+layerName);
}
layerNumbers.Add (i);
}
}
bool preChange = GUI.changed;
GUI.changed = false;
int newSelected = 0;
if (Event.current.type == EventType.MouseDown) {
newSelected = -1;
}
newSelected = EditorGUILayout.Popup (label,newSelected,layers.ToArray(),EditorStyles.layerMaskField);
if (GUI.changed && newSelected >= 0) {
//newSelected -= 1;
Debug.Log (lastEvent +" "+newSelected + " "+layerNumbers[newSelected]);
if (showSpecial && newSelected == 0) {
selected = 0;
} else if (showSpecial && newSelected == 1) {
selected = -1;
} else {
if (selected == (selected | (1 << layerNumbers[newSelected]))) {
selected &= ~(1 << layerNumbers[newSelected]);
//Debug.Log ("Set Layer "+LayerMask.LayerToName (LayerNumbers[newSelected]) + " To False "+selected.value);
} else {
//Debug.Log ("Set Layer "+LayerMask.LayerToName (LayerNumbers[newSelected]) + " To True "+selected.value);
selected = selected | (1 << layerNumbers[newSelected]);
}
}
} else {
GUI.changed = preChange;
}
return selected;
}
Awesome, thank you I'll give it a try. Only I wanted this popup for any enum mask type. I'll see if I can modify this to do what I need. Thanks.
I don't know if this will be of use to you, but please check my answer below. This might be a new feature of Unity which wasn't available previously.
You can also create custom popup menus: http://unity3d.com/support/documentation/ScriptReference/Generic$$anonymous$$enu.html
Unfortunately I cannot give you a "+" yet, but I really wanted to thank you for this solution!
Answer by Bentley · Aug 30, 2020 at 11:31 AM
This can now be done without any custom editor classes with the [Flags]
attribute:
using System;
[System.Flags]
public enum MyEnum
{
Nothing = 0,
Val1 = 1,
Val2 = 2,
Val3 = 4,
Val4 = 8
Everything = 0b1111
}
And your class/struct:
[System.Serializable]
public struct MyStruct
{
public MyEnum myValue;
}
Result:
I didn't include it as Flags
is not ambiguous in the context, but you're right—much better to be explicit, especially on an answers page. I've updated the answer to use System.Flags
. Thanks!
Answer by numberkruncher · May 28, 2012 at 04:15 PM
What about the EditorGUILayout.EnumMaskField
? http://unity3d.com/support/documentation/ScriptReference/EditorGUILayout.EnumMaskField.html
Another option might be EditorGUILayout.MaskField
if you want to define custom strings: http://unity3d.com/support/documentation/ScriptReference/EditorGUILayout.MaskField.html
Note: Specifying null
seems to insert horizontal splitter (at expense of a flag)
Answer by ikriz · Aug 10, 2015 at 08:17 AM
I believe this is what your looking for: http://wiki.unity3d.com/index.php/EnumFlagPropertyDrawer
Turn your enum into a multi flag selection variable ;)
Your answer
Follow this Question
Related Questions
Light Cookie not in Inspector 0 Answers
Set the Rect of PopupWindowContent 1 Answer
Problem with MaskField ints 1 Answer
Field in PropertyDrawer isn't remembered 1 Answer
Inspector Popup format to look like tag or layer popup 1 Answer