{"id":15161239,"url":"https://github.com/000daniel/collision-mask-layer","last_synced_at":"2026-02-03T22:02:25.195Z","repository":{"id":251783063,"uuid":"838432488","full_name":"000Daniel/Collision-Mask-Layer","owner":"000Daniel","description":"A page dedicated to explaining how collision masks/layers works in the Godot game engine","archived":false,"fork":false,"pushed_at":"2024-08-06T10:36:34.000Z","size":6029,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"MainSite","last_synced_at":"2025-04-07T22:14:24.618Z","etag":null,"topics":["collision","collision-detection","collision-layer","collision-mask","document","documentation","game-engine","godot","layer","make-easy","mask","simple","tutorial"],"latest_commit_sha":null,"homepage":"https://000daniel.github.io/Collision-Mask-Layer/","language":"HTML","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/000Daniel.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-08-05T16:18:13.000Z","updated_at":"2024-08-06T10:36:37.000Z","dependencies_parsed_at":"2024-08-05T19:17:32.992Z","dependency_job_id":"7031fe6b-68ad-4719-933d-c44e6d2c58a6","html_url":"https://github.com/000Daniel/Collision-Mask-Layer","commit_stats":{"total_commits":15,"total_committers":1,"mean_commits":15.0,"dds":0.0,"last_synced_commit":"1962d6bb90e24c4039e9c196e55d5ccd56c7a4cf"},"previous_names":["000daniel/collision-mask-layer"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/000Daniel%2FCollision-Mask-Layer","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/000Daniel%2FCollision-Mask-Layer/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/000Daniel%2FCollision-Mask-Layer/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/000Daniel%2FCollision-Mask-Layer/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/000Daniel","download_url":"https://codeload.github.com/000Daniel/Collision-Mask-Layer/tar.gz/refs/heads/MainSite","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247737786,"owners_count":20987721,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["collision","collision-detection","collision-layer","collision-mask","document","documentation","game-engine","godot","layer","make-easy","mask","simple","tutorial"],"created_at":"2024-09-27T00:01:56.491Z","updated_at":"2026-02-03T22:02:25.090Z","avatar_url":"https://github.com/000Daniel.png","language":"HTML","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\" width=\"100%\"\u003e\n    \u003ch1 align=\"center\"\u003e Introduction \u003cimg id=\"header-img\" src=\"assets/CsharpLogo_s.png\" width=\"4%\" style=\"padding: 0px 5px;\"\u003e \u003cimg id=\"header-img\" src=\"assets/GodotLogo_s.png\" width=\"4%\" style=\"padding: 0px 5px;\"\u003e\u003c/h1\u003e\n\u003c/p\u003e\n\nCollision masks and collision layers are an essential part of the Physics engine that handles how objects interact in a space(3D or 2D).\nThis page will focus on what are collision masks and collision layers and how to work with them in C#.\n\n\u003cp align=\"center\" width=\"100%\"\u003e\n\u003cimg src=\"assets/CollisionLayersNMasksGraphic.png\" width=\"40%\"\u003e\n\u003c/p\u003e\n\n## Collision Mask vs Collision Layer\n### Collision Layer\nCollision layers are the layers which the object **appears** in. \u003cbr\u003e\nLet’s take a laser wall for example, this wall will ask itself “What objects can collide with me? Who can I stop?”. \u003cbr\u003e\n\n### Collision Mask\nCollision masks are the layers that the object **scans** for collision. \u003cbr\u003e\nLet’s take a player collider for example, the collider will ask itself “What can I see? Who can stop me?” \u003cbr\u003e\n\u003cbr\u003e\n### Example\n1.  If we set the laser wall’s collision layer to 2 and collision mask to 2. \u003cbr\u003e\nAnd we set the player’s collision layer to 1 and collision mask to 1. \u003cbr\u003e\nThe player **would** be able to walk through the wall. \u003cbr\u003e\n\u003cimg src=\"assets/render_pic2.png\" width=\"55%\"\u003e\n\n2.  If we set the laser wall’s collision layer to both 1 and 2, \u003cbr\u003e\nthe player **won’t** be able to go through the wall. \u003cbr\u003e\n\n3.  If we keep the laser wall’s collision mask to 2 and collision layer to 2. \u003cbr\u003e\nAnd set the player’s collision mask to both 1 and 2. \u003cbr\u003e\nThe player **won’t** be able to pass through the wall. \u003cbr\u003e\n\u003cbr\u003e\n\n### Another example:\nLet’s say we have enemies in our game. \u003cbr\u003e\nWe set the enemies’ collision layer to 2, and set collision mask to 1. \u003cbr\u003e\nWe set the player’s collision layer to 1, and set collision mask to both 1 and 2. \u003cbr\u003e\nThe enemies would be able to walk through each other, while both the enemies and the player won’t go through each other. \u003cbr\u003e\n\u003cp align=\"left\" width=\"100%\"\u003e\n\u003cimg src=\"assets/render_pic3.png\" width=\"55%\"\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\n## Naming layers\nWorking with a lot of layer and keeping track of them could get confusing so you might find it useful to assign them a name:\nGo to “Project” → “Project Settings” → “Layer Names”.\n\u003cp align=\"left\" width=\"100%\"\u003e\n\u003cimg src=\"assets/gd_pic1-upscaled.png\" width=\"75%\"\u003e\n\u003c/p\u003e\n\u003cp align=\"left\" width=\"100%\"\u003e\n\u003cimg src=\"assets/gd_pic2-upscaled.png\" width=\"75%\"\u003e\n\u003c/p\u003e\n\u003cbr\u003e\n\n## How to use in code \u003cbr\u003e\nSometimes we will need to dynamically change the collision detection of objects, luckily there are *multiple* ways for us to do so in Godot C#. \u003cbr\u003e\n\n### Calculate layers \u003cbr\u003e\nFirst we will need to understand how both masks and layers are programmed. \u003cbr\u003e\nIn 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. \u003cbr\u003e\n*(Reading from right to left, each 1 represents an enabled layer, and each 0 represents a disabled one)* \u003cbr\u003e\nIn this example layers 1,2 and 4 are enabled: \u003cbr\u003e\n```cs\nuint mask = 0b00000000_00000000_00000000_0001011;\nCollisionMask = mask;\n```\n```cs\n\t//This can be shortened to:\nuint mask = 0b1011;\n```\nIn hexadecimal: \u003cbr\u003e\n```cs\nuint mask = 0x03F3;\n\n\t//Can be shortened to:\nuint mask = 0x3F3;\n```\n\u003cbr\u003e\n\n### Calculate with Powers of Two: \u003cbr\u003e\nEvery layer is represented with 2 by the power of the layer’s number (layer count starts at 0): \u003cbr\u003e\n```cs\nLayer 1 is 2^0 = 1\nLayer 2 is 2^1 = 2\nLayer 3 is 2^2 = 4\nLayer 4 is 2^3 = 8 \n```\nIf we add **all** the layers together we will get 4294967295 in decimal. \u003cbr\u003e\nTo ignore layers 1,2 and 4:  4294967295 -1 -2 -8 = 4294967284 \u003cbr\u003e\n```cs\nCollisionMask = 4294967284; //This will ignore only layers 1,2 and 4.\n```\n\n\u003cbr\u003e\n\n### Calculate with Bit Shifting: \u003cbr\u003e\nTo represent all the layers: \u003cbr\u003e\n```cs\nint CollisionLayers = ~0; \n```\n*(‘~’ is a Bitwise NOT operation, so it inverts the 0 into a 1, enabling all of the layers)* \u003cbr\u003e\nRemove layers with bit shifting (layer count starts at 0): \u003cbr\u003e\n```cs\n~(base_bitmask \u003c\u003c layer)\n\nExample:\nLayer 1 is ~(1 \u003c\u003c 0)\nLayer 2 is ~(1 \u003c\u003c 1)\nLayer 3 is ~(1 \u003c\u003c 2)\nLayer 4 is ~(1 \u003c\u003c 3) \n```\nIgnore only layer 2: \u003cbr\u003e\n```cs\nint mask = ~0;\nmask = mask \u0026 ~(1 \u003c\u003c 1);\nCollisionMask = (uint)mask; \n```\nIgnore only layers 8 and 16: \u003cbr\u003e\n```cs\nint mask = ~0;\nmask \u0026= ~((1 \u003c\u003c 7) | (1 \u003c\u003c 15));\nCollisionMask = (uint)mask; \n```\n[More about bit shifting](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/bitwise-and-shift-operators) \u003cbr\u003e\n\u003cbr\u003e\n### Extra reference:\n[Physics introduction](https://docs.godotengine.org/en/stable/tutorials/physics/physics_introduction.html#collision-layers-and-masks)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F000daniel%2Fcollision-mask-layer","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F000daniel%2Fcollision-mask-layer","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F000daniel%2Fcollision-mask-layer/lists"}