Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
2 captures
13 Jun 22 - 14 Jun 22
sparklines
Close Help
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
  • Asset Store
  • Get Unity

UNITY ACCOUNT

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account
  • Blog
  • Forums
  • Answers
  • Evangelists
  • User Groups
  • Beta Program
  • Advisory Panel

Navigation

  • Home
  • Products
  • Solutions
  • Made with Unity
  • Learning
  • Support & Services
  • Community
    • Blog
    • Forums
    • Answers
    • Evangelists
    • User Groups
    • Beta Program
    • Advisory Panel

Unity account

You need a Unity Account to shop in the Online and Asset Stores, participate in the Unity Community and manage your license portfolio. Login Create account

Language

  • Chinese
  • Spanish
  • Japanese
  • Korean
  • Portuguese
  • Ask a question
  • Spaces
    • Default
    • Help Room
    • META
    • Moderators
    • Topics
    • Questions
    • Users
    • Badges
  • Home /
avatar image
7
Question by Alex-Chouls · Jan 15, 2011 at 04:28 AM · guieditorwindowlayermask

How to create LayerMask field in a custom EditorWindow?

Is there a way to manually invoke the LayerMask field in an EditorWindow? Like you can with TagField or LayerField...

Comment
Add comment · Show 1
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image Shuttz · Nov 05, 2021 at 12:51 AM 0
Share

I made one code to resove that in my GitHub, check out: https://github.com/Delgado-tech/layerMaskDrawer

7 Replies

· Add your reply
  • Sort: 
avatar image
10

Answer by Llockham-Industries · Aug 01, 2017 at 06:41 AM

I know this is quite old but Vexe brought up an answer using the editor Internal namespace. I went and explored it a little and it seems it has methods built specifically for this.

First of, make sure you include - using UnityEditorInternal; at the top ;).

Then you can use a regular mask field with the methods Unity provides like such.

 LayerMask tempMask = EditorGUILayout.MaskField( InternalEditorUtility.LayerMaskToConcatenatedLayersMask(myLayerMask), InternalEditorUtility.layers);

Then you can convert that mask back to the correct value using -

 myLayerMask = InternalEditorUtility.ConcatenatedLayersMaskToLayerMask(tempMask);

Of course you can do this in a single line, but it's better demonstrated using two, and better practice to store it in a temp value so you can Undo.Record the object in a change check before applying it.

Hope this helps, Dan.

Comment
Add comment · Show 3 · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image churi24 · Aug 15, 2017 at 02:51 PM 0
Share

Perfect solution.. nice and easy.

avatar image Heinrix · Oct 03, 2019 at 10:17 AM 0
Share

This needs to be the new updated answer! Good work, thanks very much!

avatar image Eristen · Nov 21, 2020 at 01:56 PM 0
Share

Just to make sure people new at this are able to use this as well:

you need an accessible Layer$$anonymous$$ask variable in your non-editor script

 [HideInInspector] public Layer$$anonymous$$ask my$$anonymous$$ask;

then on the editor script you declare myLayer$$anonymous$$ask outside OnInspectorGUI

 Layer$$anonymous$$ask myLayer$$anonymous$$ask = new Layer$$anonymous$$ask();

then in OnInspectorGUi you do this:

     public override void OnInspectorGUI(){
       var t = ($$anonymous$$yScript)target;
 
       DrawDefaultInspector();
 
       Layer$$anonymous$$ask temp$$anonymous$$ask = EditorGUILayout.$$anonymous$$askField("$$anonymous$$y $$anonymous$$ask", InternalEditorUtility.Layer$$anonymous$$askToConcatenatedLayers$$anonymous$$ask(myLayer$$anonymous$$ask), InternalEditorUtility.layers);
       myLayer$$anonymous$$ask = InternalEditorUtility.ConcatenatedLayers$$anonymous$$askToLayer$$anonymous$$ask(temp$$anonymous$$ask);
 
       t.my$$anonymous$$ask = myLayer$$anonymous$$ask;
 
     }

avatar image
5

Answer by FlyingOstriche · Feb 21, 2015 at 07:35 PM

This one removes all empty layers. The performance runs at 0.02 over 1000 iterations.

 static LayerMask LayerMaskField( string label, LayerMask layerMask) {
     List<string> layers = new List<string>();
     List<int> layerNumbers = new List<int>();
 
     for (int i = 0; i < 32; i++) {
         string layerName = LayerMask.LayerToName(i);
         if (layerName != "") {
             layers.Add(layerName);
             layerNumbers.Add(i);
         }
     }
     int maskWithoutEmpty = 0;
     for (int i = 0; i < layerNumbers.Count; i++) {
         if (((1 << layerNumbers[i]) & layerMask.value) > 0)
             maskWithoutEmpty |= (1 << i);
     }
     maskWithoutEmpty = EditorGUILayout.MaskField( label, maskWithoutEmpty, layers.ToArray());
     int mask = 0;
     for (int i = 0; i < layerNumbers.Count; i++) {
         if ((maskWithoutEmpty & (1 << i)) > 0)
             mask |= (1 << layerNumbers[i]);
     }
     layerMask.value = mask;
     return layerMask;
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
2

Answer by Bunny83 · Jan 15, 2011 at 04:52 AM

Hmm, it looks like they forgot to implement it / make it public. I've found that little helperclass which can convert a layer into the corresponding layername and reverse: LayerMask. With this you can try to implement something similar but it won't look like the popup in the inspector.

btw. if you add a public var with this type to a script the default inspector will show that popup, but it seems that we can't invoke it manually.

Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by TowerOfBricks · Jul 26, 2012 at 07:18 PM

Here is an implementation which looks quite similar to the built in one. But it shows unnamed layers as well due to technical limitations. To prevent too much memory usage is updates the layer name list only every second... but that should be enough. I have an implementation for Unity 3.4 and earlier as well, but the code for that is a lot more hackish. But I can post it if anyone is interested.

 public static List<string> layers;
 public static List<int> layerNumbers;
 public static string[] layerNames;
 public static long lastUpdateTick;
 
 /** Displays a LayerMask field.
  * \param showSpecial Use the Nothing and Everything selections
  * \param selected Current LayerMask
  * \version Unity 3.5 and up will use the EditorGUILayout.MaskField instead of a custom written one.
  */
 public static LayerMask LayerMaskField (string label, LayerMask selected, bool showSpecial) {
     
     //Unity 3.5 and up
     
     if (layers == null || (System.DateTime.Now.Ticks - lastUpdateTick > 10000000L && Event.current.type == EventType.Layout)) {
         lastUpdateTick = System.DateTime.Now.Ticks;
         if (layers == null) {
             layers = new List<string>();
             layerNumbers = new List<int>();
             layerNames = new string[4];
         } else {
             layers.Clear ();
             layerNumbers.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));
                 layerNumbers.Add (i);
                 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;
 }
Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
avatar image
1

Answer by vexe · Jun 01, 2015 at 09:35 AM

A slightly improved version of @FlyingOstriche - no need to allocate lists. The layer names can be accessed via InternalEditorUtility in UnityEditorInternal namespace. For the numbers list, a static list seems to do the job

 static List<int> layerNumbers = new List<int>();
 
 static LayerMask LayerMaskField(string label, LayerMask layerMask)
 {
     var layers = InternalEditorUtility.layers;
 
     layerNumbers.Clear();
 
     for (int i = 0; i < layers.Length; i++)
         layerNumbers.Add(LayerMask.NameToLayer(layers[i]));
 
     int maskWithoutEmpty = 0;
     for (int i = 0; i < layerNumbers.Count; i++)
     {
         if (((1 << layerNumbers[i]) & layerMask.value) > 0)
             maskWithoutEmpty |= (1 << i);
     }
 
     maskWithoutEmpty = UnityEditor.EditorGUILayout.MaskField(label, maskWithoutEmpty, layers);
 
     int mask = 0;
     for (int i = 0; i < layerNumbers.Count; i++)
     {
         if ((maskWithoutEmpty & (1 << i)) > 0)
             mask |= (1 << layerNumbers[i]);
     }
     layerMask.value = mask;
 
     return layerMask;
 }




Comment
Add comment · Share
10 |3000 characters needed characters left characters exceeded
▼
  • Viewable by all users
  • Viewable by moderators
  • Viewable by moderators and the original poster
  • Advanced visibility
Viewable by all users
  • 1
  • 2
  • ›

Your answer

Hint: You can notify a user about this post by typing @username

Up to 2 attachments (including images) can be used with a maximum of 524.3 kB each and 1.0 MB total.

Follow this Question

Answers Answers and Comments

12 People are following this question.

avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image

Related Questions

How do I use GUI.BeginCLip() ? There is no documentation on docs.Unity 1 Answer

"You can only call GUI functions from inside OnGUI." Each time I try to open a window after a recompilation when the window was opened? 1 Answer

Display various properties in an EditorWindow 1 Answer

Create an Editor Window like Mecanim 1 Answer

Editor Window - GUI Error You are pushing more GUIClips than you are popping. 1 Answer


Enterprise
Social Q&A

Social
Subscribe on YouTube social-youtube Follow on LinkedIn social-linkedin Follow on Twitter social-twitter Follow on Facebook social-facebook Follow on Instagram social-instagram

Footer

  • Purchase
    • Products
    • Subscription
    • Asset Store
    • Unity Gear
    • Resellers
  • Education
    • Students
    • Educators
    • Certification
    • Learn
    • Center of Excellence
  • Download
    • Unity
    • Beta Program
  • Unity Labs
    • Labs
    • Publications
  • Resources
    • Learn platform
    • Community
    • Documentation
    • Unity QA
    • FAQ
    • Services Status
    • Connect
  • About Unity
    • About Us
    • Blog
    • Events
    • Careers
    • Contact
    • Press
    • Partners
    • Affiliates
    • Security
Copyright © 2020 Unity Technologies
  • Legal
  • Privacy Policy
  • Cookies
  • Do Not Sell My Personal Information
  • Cookies Settings
"Unity", Unity logos, and other Unity trademarks are trademarks or registered trademarks of Unity Technologies or its affiliates in the U.S. and elsewhere (more info here). Other names or brands are trademarks of their respective owners.
  • Anonymous
  • Sign in
  • Create
  • Ask a question
  • Spaces
  • Default
  • Help Room
  • META
  • Moderators
  • Explore
  • Topics
  • Questions
  • Users
  • Badges