Collision Layers क्यों महत्वपूर्ण हैं

Collision layers, Godot 4 में सभी physics इंटरैक्शन का आधार हैं — मूवमेंट, हिट डिटेक्शन, रेकास्टिंग, Area ट्रिगर, और बहुत कुछ। Layer और Mask के बीच अंतर को समझना महत्वपूर्ण है, और इसे गलत समझना शुरुआती के साथ-साथ अनुभवी डेवलपर्स के लिए भी सबसे आम मुश्किलों में से एक है।

Layer बनाम Mask — मानसिक मॉडल

Godot में प्रत्येक physics ऑब्जेक्ट के दो bitmask प्रॉपर्टीज़ होती हैं:

मूल नियम

A, B से टकराता है जब A का Mask, B के Layer को शामिल करता है या B का Mask, A के Layer को शामिल करता है। टकराव होने के लिए केवल एक पक्ष को दूसरे को "देखना" पर्याप्त है।

Project Settings में Layers का नामकरण

कोई भी कोड लिखने से पहले, अपने layers को नाम दें। इससे Inspector का उपयोग काफी आसान हो जाता है और जैसे-जैसे आपका प्रोजेक्ट बढ़ता है, भ्रम से बचाव होता है।

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

Layer सं. नाम उद्देश्य
1Playerप्लेयर कैरेक्टर
2Enemyसभी दुश्मन बॉडीज़
3Environmentदीवारें, फ़र्श, प्लेटफ़ॉर्म
4Projectileगोलियां, तीर, स्पेल
5Pickupआइटम, सिक्के, हेल्थ पैक
6Triggerसेंसर, स्पॉन ज़ोन, चेकपॉइंट

कोड में Layers सेट करना (GDScript)

Godot 4 दो दृष्टिकोण प्रदान करता है — वैल्यू-आधारित API (अनुशंसित) और सीधा bitmask असाइनमेंट:

# 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 का जाल

set_collision_layer_value() में Layer संख्याएं 1-आधारित होती हैं, लेकिन अंतर्निहित bitmask 0-आधारित है। Layer 1 = bit 0 = मान 1, Layer 2 = bit 1 = मान 2, Layer 3 = bit 2 = मान 4। संदेह होने पर, गलतियों से बचने के लिए वैल्यू-आधारित API का उपयोग करें।

सामान्य Layer योजनाएं

Platformer / Side-Scroller

ऑब्जेक्ट Layer Mask व्याख्या
Player12, 3, 5, 6दुश्मनों, वातावरण, पिकअप, ट्रिगर का पता लगाता है
Enemy21, 3प्लेयर और वातावरण का पता लगाता है
Environment3निष्क्रिय — दूसरों द्वारा पता लगाया जाता है
Projectile42, 3दुश्मनों और दीवारों से टकराता है
Pickup5निष्क्रिय — प्लेयर इसका पता लगाता है
Trigger61केवल प्लेयर का पता लगाता है

Top-Down / Roguelike

ऑब्जेक्ट Layer Mask व्याख्या
Player12, 3, 5, 6दुश्मनों, दीवारों, NPCs, सेंसर का पता लगाता है
Enemy21, 3प्लेयर और दीवारों का पता लगाता है
Wall3निष्क्रिय
Bullet41, 2, 3प्लेयर, दुश्मनों और दीवारों से टकराता है
NPC53केवल दीवारों से टकराता है
Sensor61प्लेयर के प्रवेश का पता लगाता है

Area2D / Area3D Layers

Areas उसी Layer/Mask सिस्टम का उपयोग करती हैं। इसके अतिरिक्त, उनके पास दो टॉगल प्रॉपर्टीज़ होती हैं:

सिग्नल: area_entered बनाम body_entered

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 नोड्स के पास केवल एक Mask होता है (कोई Layer नहीं), क्योंकि वे डिटेक्टर हैं, न कि physical बॉडीज़। रे किससे टकरा सकता है, इसे फ़िल्टर करने के लिए 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

व्यावहारिक उदाहरण: Player – Enemy – Projectile

यहां एक सामान्य एक्शन गेम के लिए एक संपूर्ण layer सेटअप है। प्रत्येक निर्णय के पीछे का तर्क कमेंट्स में दिखाया गया है:

# 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

टिप: Friendly-Fire रोकना

ध्यान दें कि Player Bullets, Layer 2 (Enemy) को मास्क करती हैं लेकिन Layer 1 (Player) को नहीं, और Enemy Bullets, Layer 1 (Player) को मास्क करती हैं लेकिन Layer 2 (Enemy) को नहीं। इस तरह आप पूरी तरह से layer कॉन्फ़िगरेशन के माध्यम से friendly-fire को रोकते हैं — बिना किसी कोड के।

डिबगिंग टिप्स

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 पैरामीटर 0-आधारित था layer पैरामीटर 1-आधारित है
20 layers उपलब्ध 32 layers उपलब्ध

माइग्रेशन का जाल

यदि आप किसी Godot 3 प्रोजेक्ट को पोर्ट कर रहे हैं, तो याद रखें कि set_collision_layer_bit(0, true) अब set_collision_layer_value(1, true) बन जाता है। इंडेक्स +1 से खिसक जाता है। यदि आप इसे चूक जाते हैं, तो आपके सभी layers एक से खिसक जाएंगे।

सामान्य गलतियां

1. Mask सेट करना भूल जाना

आपके ऑब्जेक्ट के पास एक Layer है, लेकिन Mask खाली है (सभी शून्य)। ऑब्जेक्ट physics दुनिया में मौजूद है, पर किसी का पता नहीं लगाता। मेल खाते masks वाले अन्य ऑब्जेक्ट अभी भी इसका पता लगाएंगे, लेकिन इस ऑब्जेक्ट पर move_and_slide() हर चीज़ से होकर गुज़र जाएगा।

2. Layer को Mask के साथ गड़बड़ा देना

प्लेयर के Mask के बजाय उसके Layer को 2 (Enemy) पर सेट करना। अब जहां तक physics इंजन का सवाल है, प्लेयर एक दुश्मन है। हमेशा याद रखें: Layer = मैं क्या हूं, Mask = मैं क्या स्कैन करता हूं।

3. Layer संख्याओं के बजाय Bitmask मानों का उपयोग करना

यह सोचकर set_collision_layer_value(4, true) लिखना कि यह bitmask मान 4 (Layer 1+2) सेट करता है। वास्तव में, यह Layer 4 को सक्षम करता है। वैल्यू-आधारित API, layer संख्याएं लेता है, न कि bit मान।

4. जहां दोनों तरफ की अपेक्षा हो, वहां एकतरफ़ा पता लगना

ऑब्जेक्ट A, B के Layer को मास्क करता है, लेकिन B, A के Layer को मास्क नहीं करता। A पर move_and_slide() B से टकराएगा, लेकिन B पर move_and_slide() A से होकर गुज़र जाएगा। दो CharacterBody नोड्स को एक-दूसरे को रोकने के लिए, दोनों को अपने Mask में दूसरे का Layer रखना होगा।

Godot MCP Pro के साथ Physics सेटअप को स्वचालित करें

layer चेकबॉक्स को मैन्युअल रूप से टॉगल करना बंद करें। AI को अपना पूरा collision सेटअप सेकंडों में कॉन्फ़िगर करने दें — layers के नामकरण, masks के असाइनमेंट और raycasts जोड़ने सहित।

Godot MCP Pro प्राप्त करें — $15
संबंधित टूल्स: setup_collision set_physics_layers get_physics_layers get_collision_info add_raycast