Wayback Machinekoobas.hobune.stream
May JUN Jul
Previous capture 14 Next capture
2021 2022 2023
1 capture
14 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 /
This question was closed Nov 08, 2017 at 03:25 AM by Bunny83 for the following reason:

The question is answered, right answer was accepted

This post has been wikified, any user with enough reputation can edit it.
avatar image
120
Question by Stelimar · Dec 07, 2009 at 12:08 AM · physicsraycastlayerslayermaskselect

How do I use layermasks?

Layermasks took me a while to figure out and get working correctly, and I've seen a few people asking about them on the forums, so I thought I'd add a little something to help anyone who may be struggling with them.

The question is: How do I use/create layermasks to use with, e.g., Physics.Raycast or other Physics functions? For those who don't know: a layermask allows you to specify certain layers to exclude/include in certain physics functions.

Comment
Comments Locked · 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 ReytheRed · Apr 24, 2014 at 03:26 PM 0
Share

This question and answers have been very helpful, thanks.

9 Replies

  • Sort: 
avatar image
240
Best Answer

Answer by Stelimar · Dec 07, 2009 at 12:12 AM

layermasks work by setting bits in an integer value to 0 (false) or 1 (true), which represent whether or not to test against a certain layer. The first bit from the right is used for layer 1, the second for layer 2, etc. So a value of 00000101 (decimal value of 5), which has the first and third bit set to 1 (true), will test ONLY against layers one and three.

Using bit shifting to create a layermask

The easiest way to produce a layermask is using the bit shift operator (<<). What this does is move each bit in an value to the left. So if you have a value of 6 (binary value of 00000110), and shift it two places to the left, you will be given a value of 24 (binary 00011000).

Remember that a value of 1 in decimal is 00000001 in binary. So if you bit shift 1 by n places to the left, you will end up with the nth bit being 1 and all other bits being 0. Based on this, the following code will produce a layermask which can be used to only test against the given layer:

var layer : int = 3;
var layermask : int = 1 << layer;

layermask will turn out to be 4 in decimal (00000100). Notice that the third bit is 1 (true).

Combining layermasks

To produce a layermask which will test against more than one layer, you can use the binary OR operator (|) to produce a new layermask. A bit in the new layermask is true if the corresponding bit was true in either one of the layermasks it was made from:

 var layer1 : int = 3;
 var layer2 : int = 5;
 var layermask1 : int = 1 << layer1;
 var layermask2 : int = 1 << layer2;
 var finalmask : int = layermask1 | layermask2; // Or, (1 << layer1) | (1 << layer2)
 
 // The bits look like this:
 // (00000001) First bit is true in layermask1
 // (00000100) Third bit is true in layermask2
 // (00000101) Both first and third bit are true in finalmask

(Note that adding layermasks together with (+) is usually not wanted. For example, adding two layermasks that both contain the same layer, such as 00000011 (layer 1 and 2) and 00000110 (layer 2 and 3) would produce 00001001 (layer 1 and 4), while with the bitwise OR operator (|) you get 00000111 (layer 1, 2, and 3) as expected.)

Inverting a layermask

To test for all layers except the given layer, just use the bit inverse operator (~). The bit invert operator takes every bit in an integer, and swaps it from 0 to 1 or vice versa. So ~00000010 equals 11111101, which would test for every layer except layer 2.

Note that if there are two layers you want to exclude, you need to combine the bitmasks with the OR operator before inverting:

var layer1 : int = 3;
var layer2 : int = 5;
var layermask : int = ~((1 << layer1) | (1 << layer2)) // NOT ~(1 << layer1) | ~(1 << layer2)

This would give you a value of 11101011.

I hope this helped somebody!

Comment
Comments Locked · Show 15 · 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 Statement · Dec 07, 2009 at 09:19 AM 6
Share

You shouldn't add the layermasks together. You should use the binary OR operator.

avatar image duck ♦♦ · Dec 08, 2009 at 11:11 AM 6
Share

There's another typo in this code, but I haven't reached the magic limit to be able to fix it! The 4th line in the 2nd example code has 2 << layer2 whereas it should read 1 << layer2

avatar image Owen-Reynolds · Jan 19, 2012 at 03:18 PM 6
Share

You have some off-by-ones. In the first code segment you say that 1<<3 is 100, but it's really 1000 (it shifts over by 3.) At the very top you say 001 is layer1, but it's really layer 0. In your next code segment, with layers 3 and 5, the results should be 3:1000, 5:100000 and (3|5):101000

avatar image Eric5h5 · Aug 15, 2013 at 04:56 AM 4
Share

1000 0000 0000 0000 would never be 1. A little-endian processor would store a 16-bit "1" as 00000001 00000000, but you always write the bits from left to right. It's the bytes (not bits) that are right-to-left in that case. It would be unnecessarily confusing to store layermasks as little-endian, so they are always big-endian regardless of whether the processor you're using is little- or big-endian. (You do need to be aware of endianness when using something like System.IO.BinaryReader, since in that case the order of the bytes depends on the CPU, and the framework won't handle it for you.)

avatar image unityBerserker · Jan 22, 2017 at 04:03 AM 17
Share

Now it will be easier to understand. alt text

What is faster? Enum or Layer$$anonymous$$ask ? alt text

layers-english-version1.png (119.9 kB)
layermask-vs-enums.png (85.0 kB)
Show more comments
avatar image
110

Answer by Statement · Dec 07, 2009 at 09:37 AM

This is an attempt to simplify Stelimars insightful post.

LayerMask, or any "Mask" in Computer Science, is an integer which uses its 32 bits to represent different flags. While it is an integer, the value doesn't mean anything useful numerically. What matters is which flags are turned on or off.

In the case of LayerMask, each flag (each bit) represents one layer. If you select any game object from the editor you'll notice the Layer field in the top right corner of the inspector. Clicking this will bring up a list of different layers. There are some predefined Layers, but you can also add layers. Notice how you have 32 slots for your layers. This is because Unity uses an integer type to store the flags in each of the 32 bits that makes up an integer. As we can see, Layer 8 to 31 is available for us to define for our own game.

Since Masks use a single bit to represent if some option is true or false, a Mask can contain many different options. The same goes when thinking about Layers. A LayerMask specifies which Layers are enabled for any given mechanism. This enables us to tell the game that our GameObject "Don", for example, is thought to belong to the user defined layer "NPC" and "Bob" to belong to the user defined layer "SpellCaster".

Then, we make us of this information for example in a raycast call, specifying that the raycast should only return objects that belong to the "NPC" layer. An example when this could be used is when you want to target NPCs only with the click of the mouse. Then, imagine you have a game where you want to cast a spell, and that spell can only target Spell Casters. Then you'd only include the game objects that has the SpellCaster layer enabled. A third option would be to include both NPC and SpellCaster in the search. That way we would test both Don and Bob.

Finally some technical mumbo.

Technical


A LayerMask is represented as a 32bit integer. It also has a name table for naming the different bits so it is more readily understood by us game developers. Just to give some perspective, here's how a 32 bit integer would look like if it was written.

0000 0000 0000 0000 0000 0000 0000 0000

I put a space between every 4th bit to make it easier to read.

The first bit is actually located on the right side. Think of this as being the first layer. Here's how it would look if the first bit (or layer) would be set:

0000 0000 0000 0000 0000 0000 0000 0001

Since Unity predefines 8 layers, we can display the Mask for including all of those layers as such:

0000 0000 0000 0000 0000 0000 1111 1111

And if we like to search for NPC as from the example above, given we've put it in User Layer 8 (starting from 0, this is the 9th layer), we'd mask it as:

0000 0000 0000 0000 0000 0001 0000 0000 // NPC Layer

Just for completeness, this is how you should think a mask that include NPC OR SpellCaster should look like, if we assume the SpellCaster was set to User Layer 9:

0000 0000 0000 0000 0000 0011 0000 0000 // NPC | SpellCaster Layer

Example


Allright, now that you see we're setting bits to enable the different layers, let's look at how we generate the bit field from scratch using C#. In my example, I will make three masks that can be used to query NPCs, SpellCasters, and "NPCs and SpellCasters". We'll use Physics.Raycast in our example.

Example 1: Raycast vs NPCs

 int NPCLayer = 8; 
 // This is used to illustrate which Layer we want to use.
 
 int NPCMask = 1 << NPCLayer; 
 // This is used to generate the Mask derived from NPC Layer.
 
 if Physics.Raycast(fromPosition, direction, Mathf.Infinity, NPCMask)
 {
     // We cast a ray onto a NPC!
 }

Example 2: Raycast vs SpellCasters

 int SpellCasterLayer = 9; 
 // This is used to illustrate which Layer we want to use.
 
 int SpellCasterMask = 1 << SpellCasterLayer; 
 // This is used to generate the Mask derived from SpellCaster Layer.
 
 if Physics.Raycast(fromPosition, direction, Mathf.Infinity, SpellCasterMask)
 {
     // We cast a ray onto a spell caster!
 }


Example 3: Raycast vs NPCs and SpellCasters

 int NPCLayer = 8; 
 int SpellCasterLayer = 9; 
 // This is used to illustrate which Layers we want to use.
 
 int NPCMask = 1 << NPCLayer; 
 int SpellCasterMask = 1 << SpellCasterLayer; 
 // This is used to generate the Mask derived from the layers.
 
 int CombinedMask = NPCMask | SpellCasterMask;
 // We use the binary OR operator to combine masks.
 
 if Physics.Raycast(fromPosition, direction, Mathf.Infinity, CombinedMask)
 {
     // We cast a ray onto a NPC or a SpellCaster!
 }


Stelimar also have excellent information in his posts that you should read.

Comment
Comments Locked · Show 8 · 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 Lemon · Jan 27, 2011 at 10:40 PM 0
Share

Excellent Post! Just one small point. If you are loading the layer from the string: [int NPCLayer = Layer$$anonymous$$ask.NameToLayer ("NPCLayer");] you still need to perform the mask afterwards: [int NPC$$anonymous$$ask = 1 << NPCLayer;]

avatar image ina · Dec 21, 2012 at 04:24 PM 0
Share

Would 0 << 8 equate to negating 1<<8 ?

avatar image Statement · Dec 22, 2012 at 07:08 PM 2
Share

The << operator is a shift operator. 1 << 8 means that you'd take the integer 1, and shift all bits 8 bits "to the left". 0 << 8 would return 0, since having an integer full of zero bits is still the same integer no matter which direction or how many bits you shift it.

avatar image Statement · Dec 22, 2012 at 07:10 PM 0
Share

If you want to make a mask that is all of the layers except layer 8, you'd do ~(1 << 8). http://msdn.microsoft.com/en-us/library/d2bd4x66.aspx

avatar image boddole · Mar 29, 2015 at 06:18 AM 2
Share

@$$anonymous$$ish:

I know this is a bit late...but I've used the following approach in the past to exclude a layer from a mask (I'm not saying it is the "right way" or even a good way, but it has worked for me in the past:

     public int npcComp = 8;
     public int playerComp = 9;
     public int terrain = 10;
     
     public Layer$$anonymous$$ask hittableLayers; //public just for easy display.
 
 
     void Start()
     {
         hittableLayers = (1 << npcComp) | (1 << playerComp);
         hittableLayers = hittableLayers | (1 << terrain); //'adds' terrain layer.
         hittableLayers = hittableLayers ^ (1 << terrain); //'removes' terrain layer.
     }

It occurs to me you could also do:

         hittableLayers = hittableLayers & ~(1 << terrain); //'removes' terrain layer.
Show more comments
avatar image
52

Answer by Eric5h5 · Jul 05, 2010 at 03:03 AM

While the information about layermasks in the other answers is good, it would be remiss not to mention the LayerMask type. Generally this is the easiest way to use them, since you don't have to convert anything or know anything about binary math (although it's a good idea to have that knowledge anyway, in case you want to do more complex layermask coding).

 var myLayerMask : LayerMask;
 
 if Physics.Raycast(fromPosition, direction, Mathf.Infinity, myLayerMask)
 {
     // Do something
 }

This way you can simply choose the appropriate layers in the inspector.

Comment
Comments Locked · Show 12 · 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 Tiago · Jul 21, 2010 at 07:50 AM 0
Share

Excellent information, works perfectly for general purpose. Thanks Eric!

avatar image jmpp · Apr 04, 2011 at 09:21 PM 0
Share

Regarding the use of the Layer$$anonymous$$ask type, I find myself wondering how we're actually meant to use it in Physics.Raycast(). Here you use myLayer$$anonymous$$ask but the unity documentation advises the use of myLayer$$anonymous$$ask.value. Over at #unity3D @ Freenode they tell me they both achieve the same result. What's your take?

avatar image Eric5h5 · Apr 04, 2011 at 09:43 PM 0
Share

@jmpp: They're correct; it evaluates to the integer value anyway.

avatar image franktinsley · Jul 14, 2011 at 03:24 AM 6
Share

God damn it why the hell isn't this the first thing everyone mentions!? lol I don't wanna learrrrn all this stuffffff.

avatar image DanSuper · Dec 14, 2012 at 07:35 PM 1
Share

If you're trying to access a layer mask by name you use Layer$$anonymous$$ask.NameToLayer("LAYERNA$$anonymous$$E") which returns an integer. I always use it in my code since I feel more comfortable using layer names than numbers.

Here's an example

raycastLayer$$anonymous$$ask = (1 << Layer$$anonymous$$ask.NameToLayer("World Geometry")) | (1 << Layer$$anonymous$$ask.NameToLayer("Raycast Affected Triggers"));

Show more comments
avatar image
22

Answer by DanSuper · Dec 14, 2012 at 08:31 PM

The answers above do a great job of explaining how to use LayerMasks and the technical stuff behind it. This is just a little additional information I thought people might find helpful.

I find that working with LayerMasks by name instead of layer number makes the process a lot cleaner to read.

The LayerMask class has static methods

 int NameToLayer(string layerName)   // Returns Layer Number From Layer Name
 
 string LayerToName(int layer)       // Returns Layer Name From Number


When I build LayerMasks in my scripts, I alway use the names instead of the numbers. For instance...

 lightBeamLayerMask =  (1 << LayerMask.NameToLayer("World Geometry")) 
                     | (1 << LayerMask.NameToLayer("Light Triggers"));



This way I don't have to worry about whether "World Geometry" is Layer 8, or 10.

Also, I usually store LayerMasks as private variables and build them once in the Start() method, rather than creating them immediately before using them like the Unity Scripting Reference Examples.

Comment
Comments Locked · Show 1 · 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 kirin1989 · Nov 07, 2017 at 11:05 PM 0
Share

Good considerations! Thanks for the hint!

avatar image
5

Answer by Creator347 · Aug 06, 2013 at 01:17 PM

Although you can always use the other mentioned methods to get the perfect layer-mask you desire. I'd like to point out another possibility to have the layermask. Which is actually putting the integer hardcoded. It's not recommended though, unless you've got some problems with any other method, or may be if you've a doubt that your bitwise calculations are not correct.

For eg. if you want to include layer 2 and 4 in the layermask, the calculation should be

 int mask = 1<<2 | 1<<4;

which will result into 0001 0100 which in decimal results into 20, so you can just put 20 as a layermask too.

 int mask = 20;

So instead of putting the calculation in the code, you are doing calculations yourself and putting just the result. However since it's hardcoding, I'd not recommend using this method except for debugging.

Comment
Comments Locked · Show 1 · 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 Creator347 · Aug 06, 2013 at 01:20 PM 0
Share

You can use online converters which can make this easier for you. For eg. - http://www.binaryhexconverter.com/binary-to-decimal-converter

  • 1
  • 2
  • ›

Follow this Question

Answers Answers and Comments

36 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 avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image avatar image 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

Colliders attached to objects on separate layers are colliding? 1 Answer

How to achieve this basic physics effect? Detect when to change layers 2 Answers

Is it possible to allow a raycast to pass through a collider to hit things behind it? 6 Answers

Help with Layermasks 1 Answer

Raycasting a specific square area 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