Collision Masks and Collision Layers

Godot C# collision masks and layers


Introduction

Collision masks and collision layers are an essential part of the Physics engine that handles how objects interact in a space(3D or 2D). This page will focus on what are collision masks and collision layers and how to work with them in C#.

Collision Mask vs Collision Layer

Collision Layer

Collision layers are the layers which the object appears in.
Let’s take a laser wall for example, this wall will ask itself “What objects can collide with me? Who can I stop?”.

Collision Mask

Collision masks are the layers that the object scans for collision.
Let’s take a player collider for example, the collider will ask itself “What can I see? Who can stop me?”

Example

  1. If we set the laser wall’s collision layer to 2 and collision mask to 2.
    And we set the player’s collision layer to 1 and collision mask to 1.
    The player would be able to walk through the wall.

  2. If we set the laser wall’s collision layer to both 1 and 2,
    the player won’t be able to go through the wall.

  3. If we keep the laser wall’s collision mask to 2 and collision layer to 2.
    And set the player’s collision mask to both 1 and 2.
    The player won’t be able to pass through the wall.

Another example:

Let’s say we have enemies in our game.
We set the enemies’ collision layer to 2, and set collision mask to 1.
We set the player’s collision layer to 1, and set collision mask to both 1 and 2.
The enemies would be able to walk through each other, while both the enemies and the player won’t go through each other.


Naming layers

Working with a lot of layer and keeping track of them could get confusing so you might find it useful to assign them a name: Go to “Project” → “Project Settings” → “Layer Names”.


How to use in code

Sometimes we will need to dynamically change the collision detection of objects, luckily there are multiple ways for us to do so in Godot C#.

Calculate layers

First we will need to understand how both masks and layers are programmed.
In code the layers are specified as a bitmask represented by decimal or hexadecimal notation.
(Reading from right to left, each 1 represents an enabled layer, and each 0 represents a disabled one)
In this example layers 1,2 and 4 are enabled:

uint mask = 0b00000000_00000000_00000000_0001011;
CollisionMask = mask;
	//This can be shortened to:
uint mask = 0b1011;

In hexadecimal:

uint mask = 0x03F3;

	//Can be shortened to:
uint mask = 0x3F3;


Calculate with Powers of Two:

Every layer is represented with 2 by the power of the layer’s number (layer count starts at 0):

Layer 1 is 2^0 = 1
Layer 2 is 2^1 = 2
Layer 3 is 2^2 = 4
Layer 4 is 2^3 = 8 

If we add all the layers together we will get 4294967295 in decimal.
To ignore layers 1,2 and 4: 4294967295 -1 -2 -8 = 4294967284

CollisionMask = 4294967284; //This will ignore only layers 1,2 and 4.


Calculate with Bit Shifting:

To represent all the layers:

int CollisionLayers = ~0; 

(‘~’ is a Bitwise NOT operation, so it inverts the 0 into a 1, enabling all of the layers)
Remove layers with bit shifting (layer count starts at 0):

~(base_bitmask << layer)

Example:
Layer 1 is ~(1 << 0)
Layer 2 is ~(1 << 1)
Layer 3 is ~(1 << 2)
Layer 4 is ~(1 << 3) 

Ignore only layer 2:

int mask = ~0;
mask = mask & ~(1 << 1);
CollisionMask = (uint)mask; 

Ignore only layers 8 and 16:

int mask = ~0;
mask &= ~((1 << 7) | (1 << 15));
CollisionMask = (uint)mask; 

More about bit shifting

Extra reference:

Physics introduction


Last updated on: 08/06/2024. This page is up to date with Godot 4.2.2.
Please report any errors over to the relevant GitHub repository.
Documentation maintained by 000Daniel.