Çarpışma Katmanları Neden Önemli
Çarpışma katmanları, Godot 4'teki tüm fizik etkileşimlerinin temelidir — hareket, isabet algılama, raycasting, Area tetikleyicileri ve daha fazlası. Layer ile Mask arasındaki farkı anlamak son derece önemlidir ve bunu yanlış anlamak, hem yeni başlayanların hem de deneyimli geliştiricilerin en sık karşılaştığı zorluklardan biridir.
Layer ile Mask — Zihinsel Model
Godot'taki her fizik nesnesinin iki bit maskesi özelliği vardır:
- Layer = "Ben bu katmanlarda bulunuyorum" (ne olduğum)
- Mask = "Ben bu katmanları tararım" (neyi görebildiğim / vurabildiğim)
Temel Kural
A, B ile çarpışır; A'nın maskesi B'nin katmanını içeriyorsa VEYA B'nin maskesi A'nın katmanını içeriyorsa. Bir çarpışmanın gerçekleşmesi için yalnızca bir tarafın diğerini "görmesi" yeterlidir.
Proje Ayarlarında Katmanları Adlandırma
Herhangi bir kod yazmadan önce katmanlarınızı adlandırın. Bu, Inspector'ı çok daha kolay kullanılır hâle getirir ve projeniz büyüdükçe kafa karışıklığını önler.
Proje Ayarları > Katman Adları > 2D Fizik (veya 3D Fizik):
| Katman No | Ad | Amaç |
|---|---|---|
| 1 | Player | Oyuncu karakteri |
| 2 | Enemy | Tüm düşman gövdeleri |
| 3 | Environment | Duvarlar, zeminler, platformlar |
| 4 | Projectile | Mermiler, oklar, büyüler |
| 5 | Pickup | Eşyalar, altınlar, can paketleri |
| 6 | Trigger | Sensörler, doğuş bölgeleri, kontrol noktaları |
Katmanları Kodda Ayarlama (GDScript)
Godot 4 iki yaklaşım sunar — değer tabanlı API (önerilir) ve doğrudan bit maskesi ataması:
# 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)
Bit Maskesi Tuzağı
Katman numaraları set_collision_layer_value() içinde 1 tabanlıdır, ancak altta yatan bit maskesi 0 tabanlıdır. Layer 1 = bit 0 = değer 1, Layer 2 = bit 1 = değer 2, Layer 3 = bit 2 = değer 4. Emin değilseniz, hataları önlemek için değer tabanlı API'yi kullanın.
Yaygın Katman Şemaları
Platformer / Yandan Kaydırmalı
| Nesne | Layer | Mask | Açıklama |
|---|---|---|---|
| Player | 1 | 2, 3, 5, 6 | Düşmanları, çevreyi, eşyaları, tetikleyicileri algılar |
| Enemy | 2 | 1, 3 | Oyuncuyu ve çevreyi algılar |
| Environment | 3 | — | Pasif — başkaları tarafından algılanır |
| Projectile | 4 | 2, 3 | Düşmanlara ve duvarlara isabet eder |
| Pickup | 5 | — | Pasif — oyuncu onu algılar |
| Trigger | 6 | 1 | Yalnızca oyuncuyu algılar |
Yukarıdan Bakış / Roguelike
| Nesne | Layer | Mask | Açıklama |
|---|---|---|---|
| Player | 1 | 2, 3, 5, 6 | Düşmanları, duvarları, NPC'leri, sensörleri algılar |
| Enemy | 2 | 1, 3 | Oyuncuyu ve duvarları algılar |
| Wall | 3 | — | Pasif |
| Bullet | 4 | 1, 2, 3 | Oyuncuya, düşmanlara ve duvarlara isabet eder |
| NPC | 5 | 3 | Yalnızca duvarlarla çarpışır |
| Sensor | 6 | 1 | Oyuncunun girişini algılar |
Area2D / Area3D Katmanları
Area'lar aynı Layer/Mask sistemini kullanır. Ek olarak, iki geçiş özelliğine sahiptirler:
-
monitoring—trueise, bu Area kendisine giren diğer nesneleri etkin biçimde algılar. -
monitorable—trueise, diğer Area'lar bu Area'yı algılayabilir.
Sinyaller: area_entered ile body_entered
body_entered, bir PhysicsBody (CharacterBody, RigidBody, StaticBody) Area'ya girdiğinde tetiklenir. area_entered, başka bir Area girdiğinde tetiklenir. Kullanım durumunuza uygun sinyali bağladığınızdan emin olun.
# 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 Çarpışma Maskesi
RayCast düğümlerinin yalnızca bir Mask'i vardır (Layer yoktur), çünkü bunlar fiziksel gövdeler değil algılayıcılardır. Işının neye isabet edebileceğini filtrelemek için maskeyi ayarlayın:
# 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
Pratik Örnek: Player – Enemy – Projectile
İşte tipik bir aksiyon oyunu için eksiksiz bir katman kurulumu. Yorumlar her seçimin arkasındaki mantığı gösterir:
# 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
İpucu: Dost Ateşini Önleme
Player Bullet'ların 2. katmanı (Enemy) maskelediğine ancak 1. katmanı (Player) maskelemediğine ve Enemy Bullet'ların 1. katmanı (Player) maskelediğine ancak 2. katmanı (Enemy) maskelemediğine dikkat edin. Dost ateşini tamamen katman yapılandırmasıyla — hiç kod gerekmeden — işte böyle önlersiniz.
Hata Ayıklama İpuçları
- Görünür Çarpışma Şekilleri: Editörde Debug > Visible Collision Shapes yolunu izleyerek tüm çarpışma şekillerini çalışma zamanında görüntüleyin. Bu, eksik veya hizası kaymış çarpıştırıcıları anında ortaya çıkarır.
- Inspector kontrolü: Bir düğümü seçip Inspector'da Collision > Layer ve Collision > Mask bölümlerini genişletin. Adını görmek için her bitin üzerine gelin (bunları Proje Ayarları'nda adlandırdıysanız).
-
Çalışma zamanında yazdırma: Oyun sırasında bit maskesi değerlerini doğrulamak için
print("Layer: ", collision_layer, " Mask: ", collision_mask).
Godot 3 → 4 Geçiş Değişiklikleri
| 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 parametresi 0 tabanlıydı
|
layer parametresi 1 tabanlıdır
|
| 20 katman kullanılabilir | 32 katman kullanılabilir |
Geçiş Tuzağı
Bir Godot 3 projesini taşıyorsanız, set_collision_layer_bit(0, true) ifadesinin set_collision_layer_value(1, true) hâline geldiğini unutmayın. Dizin +1 kayar. Bunu gözden kaçırırsanız tüm katmanlarınız birer birim kayar.
Sık Yapılan Hatalar
1. Maskeyi ayarlamayı unutmak
Nesnenizin bir Layer'ı var ama Mask boş (tümü sıfır). Nesne fizik dünyasında vardır ama hiçbir şeyi algılamaz. Eşleşen maskelere sahip diğer nesneler yine onu algılar, ancak bu nesne üzerindeki move_and_slide() her şeyin içinden geçer.
2. Layer ile Mask'i karıştırmak
Oyuncunun Mask'i yerine Layer'ını 2 (Enemy) olarak ayarlamak. Artık fizik motoruna göre oyuncu bir düşmandır. Şunu daima hatırlayın: Layer = ne olduğum, Mask = neyi taradığım.
3. Katman numaraları yerine bit maskesi değerlerini kullanmak
set_collision_layer_value(4, true) yazıp bunun bit maskesi değeri 4'ü (katman 1+2) ayarladığını sanmak. Gerçekte bu, 4. katmanı etkinleştirir. Değer tabanlı API, bit değerlerini değil katman numaralarını alır.
4. Çift yönlü beklenirken tek yönlü algılama
A nesnesi B'nin katmanını maskeler ama B, A'nın katmanını maskelemez. A üzerindeki move_and_slide() B ile çarpışır, ancak B üzerindeki move_and_slide() A'nın içinden geçer. İki CharacterBody düğümünün birbirini engellemesi için her ikisinin de diğerinin katmanını kendi maskesinde bulundurması gerekir.
Fizik Kurulumunu Godot MCP Pro ile Otomatikleştirin
Katman onay kutularını el ile açıp kapatmayı bırakın. Yapay zekânın tüm çarpışma kurulumunuzu saniyeler içinde yapılandırmasına izin verin — katmanları adlandırma, maskeleri atama ve raycast'ler ekleme dâhil.
Godot MCP Pro Edinin — $15setup_collision
set_physics_layers
get_physics_layers
get_collision_info
add_raycast