Created
January 7, 2026 20:30
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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