Skip to content

Instantly share code, notes, and snippets.

@Rybar
Created January 7, 2026 20:30
Show Gist options
  • Select an option

  • Save Rybar/6ebef9025de99f142c99a74d63f40de0 to your computer and use it in GitHub Desktop.

Select an option

Save Rybar/6ebef9025de99f142c99a74d63f40de0 to your computer and use it in GitHub Desktop.
for Godot 4. Drop on a Node2D with polygon2D children, get staticbody2Ds with matching colliders at runtime
extends Node2D
@export var bake_on_ready: bool = true
@export var remove_source_polygons: bool = true
@export var make_bodies_as_siblings: bool = false # false = bodies become children of this node
func _ready() -> void:
if bake_on_ready:
bake_polygons_to_static_bodies()
func bake_polygons_to_static_bodies() -> void:
# Collect first so we don't iterate a changing tree.
var polys: Array[Polygon2D] = []
for c in get_children():
if c is Polygon2D:
polys.append(c)
for src in polys:
_bake_one(src)
func _bake_one(src: Polygon2D) -> void:
# Where the new StaticBody2D will live.
var target_parent: Node = get_parent() if make_bodies_as_siblings else self
var body := StaticBody2D.new()
body.name = "%s_Body" % src.name
# Match the source polygon's transform in the scene.
# Using global_transform avoids having to reason about parent-space.
target_parent.add_child(body)
body.global_transform = src.global_transform
# --- Collision ---
var col := CollisionPolygon2D.new()
col.name = "CollisionPolygon2D"
col.polygon = src.polygon
body.add_child(col)
# --- Visual ---
var vis := Polygon2D.new()
vis.name = "Polygon2D"
vis.polygon = src.polygon
vis.color = src.color
vis.texture = src.texture
vis.texture_offset = src.texture_offset
vis.texture_rotation = src.texture_rotation
vis.texture_scale = src.texture_scale
vis.invert_enabled = src.invert_enabled
vis.invert_border = src.invert_border
vis.antialiased = src.antialiased
# Note: UVs are optional; if you authored them, copy them too.
vis.uv = src.uv
body.add_child(vis)
# Optional: Keep collision/visual aligned with any local offset the source polygon had.
# Because we set body.global_transform to src.global_transform, we generally want children at identity.
col.position = Vector2.ZERO
vis.position = Vector2.ZERO
if remove_source_polygons:
src.queue_free()
else:
src.visible = false
src.set_process(false)
src.set_physics_process(false)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment