An open API service indexing awesome lists of open source software.

https://github.com/000daniel/collision-mask-layer

A page dedicated to explaining how collision masks/layers works in the Godot game engine
https://github.com/000daniel/collision-mask-layer

collision collision-detection collision-layer collision-mask document documentation game-engine godot layer make-easy mask simple tutorial

Last synced: 5 months ago
JSON representation

A page dedicated to explaining how collision masks/layers works in the Godot game engine

Awesome Lists containing this project

README

          


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](https://en.wikipedia.org/wiki/Decimal) or [hexadecimal](https://en.wikipedia.org/wiki/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:

```cs
uint mask = 0b00000000_00000000_00000000_0001011;
CollisionMask = mask;
```
```cs
//This can be shortened to:
uint mask = 0b1011;
```
In hexadecimal:

```cs
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):

```cs
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

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


### Calculate with Bit Shifting:

To represent all the layers:

```cs
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):

```cs
~(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:

```cs
int mask = ~0;
mask = mask & ~(1 << 1);
CollisionMask = (uint)mask;
```
Ignore only layers 8 and 16:

```cs
int mask = ~0;
mask &= ~((1 << 7) | (1 << 15));
CollisionMask = (uint)mask;
```
[More about bit shifting](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators)



### Extra reference:
[Physics introduction](https://docs.godotengine.org/en/stable/tutorials/physics/physics_introduction.html#collision-layers-and-masks)