Why Collision Layers Matter コリジョンレイヤーが重要な理由
Collision layers are the foundation of all physics interactions in Godot 4 — movement, hit detection, raycasting, area triggers, and more. Understanding the difference between Layer and Mask is crucial, and misunderstanding it is one of the most common pain points for beginners and experienced developers alike. コリジョンレイヤーは Godot 4 における全ての物理インタラクション(移動、ヒット判定、レイキャスト、Area トリガーなど)の基盤です。Layer と Mask の違いを正しく理解することは極めて重要で、これを誤解することが初心者にも経験者にも最もよくある落とし穴の一つです。
Layer vs Mask — The Mental Model Layer vs Mask — 考え方
Every physics object in Godot has two bitmask properties: Godot のすべての物理オブジェクトは 2 つのビットマスクプロパティを持ちます:
- Layer = "I exist on these layers" (what I am) 「自分はこのレイヤーに存在する」(自分が何であるか)
- Mask = "I scan these layers" (what I can see / hit) 「自分はこのレイヤーをスキャンする」(自分が見える/当たれる対象)
Key Rule 重要なルール
A collides with B when A's mask includes B's layer OR B's mask includes A's layer. Only one side needs to "see" the other for a collision to occur. A と B が衝突するのは、A の Mask に B の Layer が含まれている、または B の Mask に A の Layer が含まれている場合です。片方が相手を「見て」いれば衝突は発生します。
Naming Layers in Project Settings プロジェクト設定でレイヤーに名前をつける
Before writing any code, name your layers. This makes the Inspector far easier to use and prevents confusion as your project grows. コードを書く前に、まずレイヤーに名前をつけましょう。インスペクターが格段に使いやすくなり、プロジェクトが大きくなっても混乱を防げます。
Project Settings > Layer Names > 2D Physics (or 3D Physics): プロジェクト設定 > レイヤー名 > 2D 物理(または 3D 物理):
| Layer #レイヤー番号 | Name名前 | Purpose用途 |
|---|---|---|
| 1 | Player | The player characterプレイヤーキャラクター |
| 2 | Enemy | All enemy bodies全ての敵キャラクター |
| 3 | Environment | Walls, floors, platforms壁、床、プラットフォーム |
| 4 | Projectile | Bullets, arrows, spells弾丸、矢、魔法 |
| 5 | Pickup | Items, coins, health packsアイテム、コイン、回復パック |
| 6 | Trigger | Sensors, spawn zones, checkpointsセンサー、スポーンゾーン、チェックポイント |
Setting Layers in Code (GDScript) コードでレイヤーを設定する (GDScript)
Godot 4 provides two approaches — the value-based API (recommended) and direct bitmask assignment: Godot 4 では 2 つの方法があります — 値ベースの API(推奨)と、ビットマスクの直接代入です:
# Godot 4 API — value-based (1-indexed, recommended)
set_collision_layer_value(1, true) # I am on layer 1
set_collision_mask_value(2, true) # I detect layer 2
# Or use bitmask directly
collision_layer = 1 # Layer 1 only (bit 0)
collision_mask = 6 # Layers 2 and 3 (bits 1 + 2 = 6)
# Read current state
var on_layer_1: bool = get_collision_layer_value(1)
var scans_layer_2: bool = get_collision_mask_value(2)
Bitmask Gotcha ビットマスクの注意点
Layer numbers are 1-based in set_collision_layer_value(), but the underlying bitmask is 0-based. Layer 1 = bit 0 = value 1, Layer 2 = bit 1 = value 2, Layer 3 = bit 2 = value 4. When in doubt, use the value-based API to avoid mistakes.
set_collision_layer_value() のレイヤー番号は 1始まり ですが、内部のビットマスクは 0始まり です。レイヤー1 = bit 0 = 値 1、レイヤー2 = bit 1 = 値 2、レイヤー3 = bit 2 = 値 4。迷ったら値ベースの API を使いましょう。
Common Layer Schemes よくあるレイヤー構成例
Platformer / Side-scroller プラットフォーマー / 横スクロール
| Objectオブジェクト | Layer | Mask | Explanation説明 |
|---|---|---|---|
| Player | 1 | 2, 3, 5, 6 | Detects enemies, environment, pickups, triggers敵、環境、アイテム、トリガーを検出 |
| Enemy | 2 | 1, 3 | Detects player and environmentプレイヤーと環境を検出 |
| Environment | 3 | — | Passive — detected by others受動的 — 他から検出される |
| Projectile | 4 | 2, 3 | Hits enemies and walls敵と壁に当たる |
| Pickup | 5 | — | Passive — player detects it受動的 — プレイヤーが検出 |
| Trigger | 6 | 1 | Detects player onlyプレイヤーのみ検出 |
Top-down / Roguelike トップダウン / ローグライク
| Objectオブジェクト | Layer | Mask | Explanation説明 |
|---|---|---|---|
| Player | 1 | 2, 3, 5, 6 | Detects enemies, walls, NPCs, sensors敵、壁、NPC、センサーを検出 |
| Enemy | 2 | 1, 3 | Detects player and wallsプレイヤーと壁を検出 |
| Wall | 3 | — | Passive受動的 |
| Bullet | 4 | 1, 2, 3 | Hits player, enemies, and wallsプレイヤー、敵、壁に当たる |
| NPC | 5 | 3 | Collides with walls only壁のみと衝突 |
| Sensor | 6 | 1 | Detects player entryプレイヤーの進入を検出 |
Area2D / Area3D Layers Area2D / Area3D のレイヤー
Areas use the same Layer/Mask system. Additionally, they have two toggle properties: Area も同じ Layer/Mask システムを使います。さらに 2 つのトグルプロパティがあります:
-
monitoring— Iftrue, this Area actively detects other objects entering it.trueにすると、この Area が他のオブジェクトの進入を能動的に検出します。 -
monitorable— Iftrue, other Areas can detect this Area.trueにすると、他の Area がこの Area を検出できます。
Signals: area_entered vs body_entered シグナル: area_entered vs body_entered
body_entered fires when a PhysicsBody (CharacterBody, RigidBody, StaticBody) enters the Area. area_entered fires when another Area enters. Make sure you connect the right signal for your use case.
body_entered は PhysicsBody(CharacterBody、RigidBody、StaticBody)が Area に入った時に発火します。area_entered は別の Area が入った時に発火します。用途に合ったシグナルを接続してください。
# Pickup Area2D — detect when the Player body enters
func _ready() -> void:
body_entered.connect(_on_body_entered)
func _on_body_entered(body: Node2D) -> void:
if body.is_in_group("player"):
collect()
queue_free()
RayCast Collision Mask RayCast のコリジョンマスク
RayCast nodes only have a Mask (no Layer) because they are detectors, not physical bodies. Set the mask to filter what the ray can hit: RayCast ノードには Mask のみがあります(Layer はありません)。検出器であり物理ボディではないためです。Mask を設定してレイの衝突対象をフィルタリングします:
# RayCast that only detects enemies (layer 2)
$RayCast2D.collision_mask = 2 # Layer 2 = Enemy
# Or use the value-based API:
$RayCast2D.set_collision_mask_value(1, false) # Ignore Player
$RayCast2D.set_collision_mask_value(2, true) # Detect Enemy
$RayCast2D.set_collision_mask_value(3, false) # Ignore Environment
# Line-of-sight ray that ignores projectiles
$LineOfSight.collision_mask = 0
$LineOfSight.set_collision_mask_value(1, true) # Player
$LineOfSight.set_collision_mask_value(3, true) # Environment
Practical Example: Player – Enemy – Projectile 実践例: Player – Enemy – Projectile
Here is a complete layer setup for a typical action game. Comments show the reasoning behind each choice: 典型的なアクションゲーム向けの完全なレイヤー設定です。各選択の理由をコメントで示します:
# Player (CharacterBody2D)
# Layer: 1 (Player) — "I am the player"
# Mask: 2 (Enemy), 3 (Environment), 5 (Pickup)
# — I collide with enemies, walls, and can pick up items
# Enemy (CharacterBody2D)
# Layer: 2 (Enemy) — "I am an enemy"
# Mask: 1 (Player), 3 (Environment)
# — I collide with the player and walls
# Player Bullet (Area2D)
# Layer: 4 (Projectile) — "I am a projectile"
# Mask: 2 (Enemy), 3 (Environment)
# — I hit enemies and walls, but NOT the player who fired me
# Enemy Bullet (Area2D)
# Layer: 4 (Projectile) — "I am a projectile"
# Mask: 1 (Player), 3 (Environment)
# — I hit the player and walls, but NOT the enemy who fired me
Tip: Friendly Fire Prevention ヒント: フレンドリーファイアの防止
Notice that Player Bullets mask layer 2 (Enemy) but not layer 1 (Player), and Enemy Bullets mask layer 1 (Player) but not layer 2 (Enemy). This is how you prevent friendly fire purely through layer configuration — no code needed. Player Bullet はレイヤー2(Enemy)をマスクしますがレイヤー1(Player)はマスクしません。Enemy Bullet はレイヤー1(Player)をマスクしますがレイヤー2(Enemy)はマスクしません。これがレイヤー設定だけでフレンドリーファイアを防ぐ方法です — コード不要です。
Debugging Tips デバッグのヒント
- Visible Collision Shapes: In the editor, go to Debug > Visible Collision Shapes to render all collision shapes at runtime. This immediately reveals missing or misaligned colliders. コリジョンシェイプの表示: エディタでデバッグ > コリジョンシェイプを表示を有効にすると、実行時に全てのコリジョンシェイプが描画されます。欠落やズレのあるコライダーをすぐに発見できます。
- Inspector check: Select a node and expand Collision > Layer and Collision > Mask in the Inspector. Hover over each bit to see its name (if you named them in Project Settings). インスペクターで確認: ノードを選択し、インスペクターでCollision > Layer と Collision > Mask を展開します。各ビットにカーソルを合わせると名前が表示されます(プロジェクト設定で命名済みの場合)。
-
Print at runtime:
print("Layer: ", collision_layer, " Mask: ", collision_mask)to verify bitmask values during gameplay. ランタイムで確認:print("Layer: ", collision_layer, " Mask: ", collision_mask)でゲームプレイ中のビットマスク値を確認できます。
Godot 3 → 4 Migration Changes Godot 3 → 4 の移行変更点
| Godot 3 | Godot 4 |
|---|---|
set_collision_layer_bit(bit, value) |
set_collision_layer_value(layer, value) |
set_collision_mask_bit(bit, value) |
set_collision_mask_value(layer, value) |
bit parameter was 0-based
bit パラメータは 0始まり
|
layer parameter is 1-based
layer パラメータは 1始まり
|
| 20 layers available 20 レイヤー使用可能 | 32 layers available 32 レイヤー使用可能 |
Migration Pitfall 移行時の落とし穴
If you are porting a Godot 3 project, remember that set_collision_layer_bit(0, true) becomes set_collision_layer_value(1, true). The index shifts by +1. Miss this and all your layers will be off by one.
Godot 3 プロジェクトを移植する場合、set_collision_layer_bit(0, true) は set_collision_layer_value(1, true) になります。インデックスが +1 ずれます。これを見落とすと全てのレイヤーが 1 つずれてしまいます。
Common Mistakes よくあるミス
1. Forgetting to set the Mask 1. Mask の設定忘れ
Your object has a Layer but Mask is empty (all zeros). The object exists in the physics world but does not detect anything. Other objects with matching masks will still detect it, but move_and_slide() on this object will pass through everything.
オブジェクトに Layer はあるが Mask が空(全てゼロ)。オブジェクトは物理世界に存在しますが、何も検出しません。マスクが一致する他のオブジェクトからは検出されますが、このオブジェクトの move_and_slide() は全てをすり抜けます。
2. Confusing Layer with Mask 2. Layer と Mask の混同
Setting the Player's Layer to 2 (Enemy) instead of its Mask. Now the player is an enemy as far as the physics engine is concerned. Always remember: Layer = what I am, Mask = what I scan. プレイヤーの Mask ではなく Layer を 2(Enemy)に設定してしまう。物理エンジンからするとプレイヤーが敵になってしまいます。常に覚えておきましょう:Layer = 自分が何か、Mask = 何をスキャンするか。
3. Using bitmask values instead of layer numbers 3. レイヤー番号の代わりにビットマスク値を使う
Writing set_collision_layer_value(4, true) thinking it sets bitmask value 4 (layers 1+2). In reality, it enables layer 4. The value-based API takes layer numbers, not bit values.
set_collision_layer_value(4, true) でビットマスク値 4(レイヤー1+2)を設定したつもりが、実際にはレイヤー4を有効にしています。値ベースの API はビット値ではなくレイヤー番号を取ります。
4. One-way detection when bidirectional is expected 4. 双方向を期待しているのに片方向だけ検出される
Object A masks B's layer but B does not mask A's layer. move_and_slide() on A will collide with B, but move_and_slide() on B will pass through A. For two CharacterBody nodes to block each other, both need the other's layer in their mask.
A が B のレイヤーをマスクしているが、B は A のレイヤーをマスクしていない。A の move_and_slide() は B と衝突しますが、B の move_and_slide() は A をすり抜けます。2 つの CharacterBody が互いにブロックするには、両方が相手のレイヤーを自分のマスクに含める必要があります。
Automate Physics Setup with Godot MCP Pro Godot MCP Pro で物理設定を自動化
Stop manually toggling layer checkboxes. Let AI configure your entire collision setup in seconds — including naming layers, assigning masks, and adding raycasts. レイヤーのチェックボックスを手動で切り替えるのはやめましょう。AI がレイヤーの命名、マスクの割り当て、レイキャストの追加を含むコリジョン設定全体を数秒で構成します。
Get Godot MCP Pro — $5 Godot MCP Pro を入手 — $5setup_collision
set_physics_layers
get_physics_layers
get_collision_info
add_raycast