- Home /
Custom Inspector Layer Mask variable
Hi,
I am trying to create a custom editor script for the inspector. I have managed to create the fields for my floats and booleans but cannot work out how i can create a field for my layermask. I have tried using "serializedObject" but could not get it to work.
Can someone show me how i can create a field for my layer mask in my custom inspector ?
Thanks
Answer by GamesDeveloper12 · Sep 28, 2015 at 03:38 PM
I managed to resolve the issue through looking through the code of a plugin i own.
I created a script called "EditorTools":
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
public class EditorTools{
static List<string> layers;
static string[] layerNames;
public static LayerMask LayerMaskField (string label, LayerMask selected) {
if (layers == null) {
layers = new List<string>();
layerNames = new string[4];
} else {
layers.Clear ();
}
int emptyLayers = 0;
for (int i=0;i<32;i++) {
string layerName = LayerMask.LayerToName (i);
if (layerName != "") {
for (;emptyLayers>0;emptyLayers--) layers.Add ("Layer "+(i-emptyLayers));
layers.Add (layerName);
} else {
emptyLayers++;
}
}
if (layerNames.Length != layers.Count) {
layerNames = new string[layers.Count];
}
for (int i=0;i<layerNames.Length;i++) layerNames[i] = layers[i];
selected.value = EditorGUILayout.MaskField (label,selected.value,layerNames);
return selected;
}
}
and then in my editor "OnInspectorGUI" function i call:
test.Mask = EditorTools.LayerMaskField("Mask",test.Mask);
test being the name of the script im targeting.
Hope this helps other people who have the same problem :)
Answer by flamewave000 · Jun 10, 2017 at 07:26 PM
I was recently trying to do this and found a little bit more of a streamlined approach. I made two methods which convert a MaskField to a LayerMask and vice versa. Then you could use them inline with your regular gui script.
// Converts the field value to a LayerMask
private LayerMask FieldToLayerMask(int field)
{
LayerMask mask = 0;
var layers = InternalEditorUtility.layers;
for (int c = 0; c < layers.Length; c++)
{
if ((field & (1 << c)) != 0)
{
mask |= 1 << LayerMask.NameToLayer(layers[c]);
}
}
return mask;
}
// Converts a LayerMask to a field value
private int LayerMaskToField(LayerMask mask)
{
int field = 0;
var layers = InternalEditorUtility.layers;
for (int c = 0; c < layers.Length; c++)
{
if ((mask & (1 << LayerMask.NameToLayer(layers[c]))) != 0)
{
field |= 1 << c;
}
}
return field;
}
You can then use the methods as so:
EditorGUI.BeginChangeCheck();
var layersSelection = EditorGUILayout.MaskField("Layers", LayerMaskToField(script.layerMask), InternalEditorUtility.layers);
if (EditorGUI.EndChangeCheck())
{
Undo.RecordObject(script, "Layers changed");
script.layerMask= FieldToLayerMask(layersSelection);
}
I don't know the efficiency of the script, but it didn't matter too much to me since it's for the editor and not the game itself :P