Mengapa Collision Layer Penting

Collision layer adalah fondasi dari semua interaksi fisika di Godot 4 — pergerakan, deteksi tumbukan, raycasting, pemicu area, dan lainnya. Memahami perbedaan antara Layer dan Mask sangatlah penting, dan salah memahaminya adalah salah satu titik pusing yang paling umum baik bagi pemula maupun developer berpengalaman.

Layer vs Mask — Model Berpikir

Setiap objek fisika di Godot memiliki dua properti bitmask:

Aturan Utama

A bertumbukan dengan B ketika mask A memuat layer B ATAU mask B memuat layer A. Hanya satu sisi yang perlu "melihat" sisi lainnya agar tumbukan terjadi.

Menamai Layer di Project Settings

Sebelum menulis kode apa pun, namai layer-mu. Ini membuat Inspector jauh lebih mudah digunakan dan mencegah kebingungan seiring bertumbuhnya proyekmu.

Project Settings > Layer Names > 2D Physics (atau 3D Physics):

Layer # Nama Tujuan
1PlayerKarakter pemain
2EnemySemua body musuh
3EnvironmentDinding, lantai, platform
4ProjectilePeluru, panah, mantra
5PickupItem, koin, paket kesehatan
6TriggerSensor, zona spawn, checkpoint

Mengatur Layer di Kode (GDScript)

Godot 4 menyediakan dua pendekatan — API berbasis nilai (direkomendasikan) dan penetapan bitmask langsung:

# 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)

Jebakan Bitmask

Nomor layer bersifat berbasis 1 pada set_collision_layer_value(), tetapi bitmask yang mendasarinya bersifat berbasis 0. Layer 1 = bit 0 = nilai 1, Layer 2 = bit 1 = nilai 2, Layer 3 = bit 2 = nilai 4. Jika ragu, gunakan API berbasis nilai untuk menghindari kesalahan.

Skema Layer yang Umum

Platformer / Side-scroller

Objek Layer Mask Penjelasan
Player12, 3, 5, 6Mendeteksi musuh, environment, pickup, trigger
Enemy21, 3Mendeteksi pemain dan environment
Environment3Pasif — dideteksi oleh yang lain
Projectile42, 3Mengenai musuh dan dinding
Pickup5Pasif — pemain mendeteksinya
Trigger61Mendeteksi pemain saja

Top-down / Roguelike

Objek Layer Mask Penjelasan
Player12, 3, 5, 6Mendeteksi musuh, dinding, NPC, sensor
Enemy21, 3Mendeteksi pemain dan dinding
Wall3Pasif
Bullet41, 2, 3Mengenai pemain, musuh, dan dinding
NPC53Bertumbukan hanya dengan dinding
Sensor61Mendeteksi masuknya pemain

Layer Area2D / Area3D

Area menggunakan sistem Layer/Mask yang sama. Selain itu, mereka memiliki dua properti toggle:

Signal: area_entered vs body_entered

body_entered terpicu ketika sebuah PhysicsBody (CharacterBody, RigidBody, StaticBody) memasuki Area. area_entered terpicu ketika Area lain memasukinya. Pastikan kamu menghubungkan signal yang tepat untuk kasus penggunaanmu.

# 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()

Collision Mask RayCast

Node RayCast hanya memiliki Mask (tanpa Layer) karena mereka adalah detektor, bukan body fisik. Atur mask untuk memfilter apa yang bisa dikenai oleh sinar:

# 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

Contoh Praktis: Player – Enemy – Projectile

Berikut adalah penyiapan layer lengkap untuk game aksi pada umumnya. Komentar menunjukkan alasan di balik setiap pilihan:

# 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

Tips: Mencegah Friendly Fire

Perhatikan bahwa Player Bullet me-mask layer 2 (Enemy) tetapi tidak layer 1 (Player), dan Enemy Bullet me-mask layer 1 (Player) tetapi tidak layer 2 (Enemy). Inilah cara mencegah friendly fire murni melalui konfigurasi layer — tanpa perlu kode.

Tips Debugging

Perubahan Migrasi 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)
Parameter bit berbasis 0 Parameter layer bersifat berbasis 1
20 layer tersedia 32 layer tersedia

Jebakan Migrasi

Jika kamu mem-porting proyek Godot 3, ingat bahwa set_collision_layer_bit(0, true) menjadi set_collision_layer_value(1, true). Indeksnya bergeser +1. Kalau terlewat, semua layer-mu akan meleset satu.

Kesalahan Umum

1. Lupa mengatur Mask

Objekmu memiliki Layer tetapi Mask-nya kosong (semua nol). Objek itu ada di dunia fisika tetapi tidak mendeteksi apa pun. Objek lain dengan mask yang cocok tetap akan mendeteksi -nya, tetapi move_and_slide() pada objek ini akan menembus segalanya.

2. Mengacaukan Layer dengan Mask

Mengatur Layer pemain ke 2 (Enemy) alih-alih Mask-nya. Kini pemain adalah musuh menurut engine fisika. Selalu ingat: Layer = siapa aku, Mask = apa yang kupindai.

3. Menggunakan nilai bitmask alih-alih nomor layer

Menulis set_collision_layer_value(4, true) dengan anggapan itu mengatur nilai bitmask 4 (layer 1+2). Kenyataannya, ia mengaktifkan layer 4. API berbasis nilai menerima nomor layer, bukan nilai bit.

4. Deteksi satu arah padahal diharapkan dua arah

Objek A me-mask layer B tetapi B tidak me-mask layer A. move_and_slide() pada A akan bertumbukan dengan B, tetapi move_and_slide() pada B akan menembus A. Agar dua node CharacterBody saling menghalangi, keduanya perlu memiliki layer satu sama lain di mask-nya.

Otomatiskan Penyiapan Fisika dengan Godot MCP Pro

Berhentilah mengaktifkan kotak centang layer secara manual. Biarkan AI mengonfigurasi seluruh penyiapan collision-mu dalam hitungan detik — termasuk menamai layer, menetapkan mask, dan menambahkan raycast.

Dapatkan Godot MCP Pro — $15
Alat terkait: setup_collision set_physics_layers get_physics_layers get_collision_info add_raycast