From godot-ai-builder
Collision layers, physics bodies, Area2D triggers, and detection patterns. Use when setting up collision, creating hitboxes, or debugging physics issues.
npx claudepluginhub hubdev-ai/godot-ai-builderThis skill uses the workspace's default tool permissions.
| Layer | Bit | Purpose | Body Type |
Guides Godot 4.3+ physics systems: bodies, collision shapes, raycasting, areas, rigid bodies, ragdolls, soft bodies, Jolt physics, and interpolation via GDScript/C# examples.
Constructs Godot scenes from patterns like platformer characters, top-down chars, UI screens, projectiles, pickups, tilemaps with required companion nodes (e.g., CollisionShape2D).
Provides Godot 4 GDScript patterns for architecture, signals, scenes, state machines, and optimization. Useful for building games, game systems, and best practices.
Share bugs, ideas, or general feedback.
| Layer | Bit | Purpose | Body Type |
|---|---|---|---|
| 1 | 1 | Player body | CharacterBody2D |
| 2 | 2 | Player projectiles | Area2D |
| 3 | 4 | Player hitbox | Area2D |
| 4 | 8 | Enemy bodies | CharacterBody2D |
| 5 | 16 | Enemy projectiles | Area2D |
| 6 | 32 | Environment/walls | StaticBody2D |
| 7 | 64 | Pickups/items | Area2D |
| 8 | 128 | Triggers/zones | Area2D |
Player bullet (L2, M4) → detects enemy bodies (L4)
Enemy bullet (L5, M1) → detects player body (L1)
Player body (L1, M4|6) → collides with enemies + walls
Enemy body (L4, M1|6) → collides with player + walls
Pickup (L7, M1) → detects player body
Trigger zone (L8, M1) → detects player entering
# For: player, enemies, NPCs
extends CharacterBody2D
func _physics_process(delta):
velocity = direction * speed
move_and_slide()
# After move_and_slide(), check:
# is_on_floor(), is_on_wall(), is_on_ceiling()
# get_slide_collision_count(), get_slide_collision(i)
# For: crates, balls, ragdoll, debris
extends RigidBody2D
func _ready():
mass = 2.0
gravity_scale = 1.0
func push(direction: Vector2, force: float):
apply_impulse(direction * force)
# For: walls, ground, platforms
# Just add CollisionShape2D children
# No script needed usually
# For: bullets, pickups, triggers, hitboxes
extends Area2D
func _ready():
body_entered.connect(_on_body_entered) # Detects CharacterBody2D/RigidBody2D
area_entered.connect(_on_area_entered) # Detects other Area2D
body_exited.connect(_on_body_exited)
func _on_body_entered(body: Node2D):
if body.is_in_group("player"):
# Player entered this area
pass
# Rectangle
var rect = RectangleShape2D.new()
rect.size = Vector2(32, 32)
# Circle
var circle = CircleShape2D.new()
circle.radius = 16.0
# Capsule (for characters)
var capsule = CapsuleShape2D.new()
capsule.radius = 12.0
capsule.height = 32.0
# Segment (thin line, for raycasts/walls)
var segment = SegmentShape2D.new()
segment.a = Vector2(-50, 0)
segment.b = Vector2(50, 0)
# Direct assignment
body.collision_layer = 1 # Layer 1 only
body.collision_mask = 4 | 6 # Layers 3 and 4 (bits 4 + 32 = not right)
# Actually, layers are bit positions:
# Layer 1 = bit 1 = value 1
# Layer 2 = bit 2 = value 2
# Layer 3 = bit 3 = value 4
# Layer 4 = bit 4 = value 8
# Layer 5 = bit 5 = value 16
# Layer 6 = bit 6 = value 32
# So for "detect layers 4 and 6":
body.collision_mask = 8 | 32 # = 40
# Helper: set specific layer
body.set_collision_layer_value(1, true) # Enable layer 1
body.set_collision_mask_value(4, true) # Detect layer 4
body.set_collision_mask_value(6, true) # Detect layer 6
player.collision_layer = 1 # Is on layer 1
player.set_collision_mask_value(4, true) # Detect enemies
player.set_collision_mask_value(6, true) # Detect walls
enemy.collision_layer = 8 # Layer 4 (bit 4 = 8)
enemy.set_collision_mask_value(1, true) # Detect player
enemy.set_collision_mask_value(6, true) # Detect walls
bullet.collision_layer = 2 # Layer 2
bullet.collision_mask = 8 # Detect layer 4 (enemies)
pickup.collision_layer = 64 # Layer 7
pickup.collision_mask = 1 # Detect layer 1 (player)
var ray = RayCast2D.new()
ray.target_position = Vector2(200, 0) # Ray length and direction
ray.collision_mask = 1 | 32 # Detect player and walls
add_child(ray)
ray.enabled = true
# Check in _physics_process:
if ray.is_colliding():
var collider = ray.get_collider()
if collider.is_in_group("player"):
# Can see the player!
pass
# On StaticBody2D's CollisionShape2D:
shape.one_way_collision = true
# Player falls through from below, lands from above
# On anything that can be damaged
func take_damage(amount: int):
health -= amount
# Flash red
modulate = Color.RED
var tw = create_tween()
tw.tween_property(self, "modulate", Color.WHITE, 0.15)
if health <= 0:
die()
func die():
# Notify score system
var main = get_tree().current_scene
if main.has_method("add_score"):
main.add_score(100)
queue_free()