Skip to content

Instantly share code, notes, and snippets.

@afk-mario
Created November 5, 2021 17:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save afk-mario/d1324b6cae73cdc5c3238e1047c2d96b to your computer and use it in GitHub Desktop.
Save afk-mario/d1324b6cae73cdc5c3238e1047c2d96b to your computer and use it in GitHub Desktop.
Hacky Godot plugin to batch change collision layers and masks of static bodies inside packed scenes inside a directory
tool
extends EditorPlugin
var COLLISION_LAYER = 1
var COLLISION_MASK = 0
var dock
var layer_input: SpinBox
var mask_input: SpinBox
var verbose_input: CheckButton
func _enter_tree():
dock = preload("./dock.tscn").instance()
var button = dock.get_node("Container/Button")
button.connect("pressed", self, "set_collisions")
layer_input = dock.get_node("Container/CollisionLayer/SpinBox")
mask_input = dock.get_node("Container/CollisionMask/SpinBox")
verbose_input = dock.get_node("Container/Verbose/CheckButton")
add_control_to_dock(DOCK_SLOT_RIGHT_BL, dock)
func _exit_tree():
remove_control_from_docks(dock)
dock.free()
func set_collisions() -> void:
var collision_layer: int= int(layer_input.get_line_edit().text)
var collision_mask: int= int(mask_input.get_line_edit().text)
talk("Setting collision layers and masks")
var interface = get_editor_interface()
var path = interface.get_current_path()
var nodesPaths = get_dir_children(path)
for nodePath in nodesPaths:
var res = ResourceLoader.load(nodePath)
if res is PackedScene:
handle_packed_scene(res)
func handle_packed_scene(res: PackedScene) -> void:
var node = res.instance()
talk("\n %s" % node.get_name())
var static_bodies = get_static_bodies(node)
for body in static_bodies:
handle_static_body(body)
if len(static_bodies) == 0:
return
var packed_scene = PackedScene.new()
packed_scene.pack(node)
var error = ResourceSaver.save(res.resource_path, packed_scene)
if error:
push_error(error)
func get_static_bodies(node: Node) -> Array:
var nodes = []
if node is StaticBody:
nodes.append(node)
for child in node.get_children():
if child.get_child_count() > 0:
nodes.append_array(get_static_bodies(child))
elif child is StaticBody:
nodes.append(child)
return nodes
func handle_static_body(body: StaticBody) -> void:
print("\n%s" % body.name)
talk("collision layer: %s -> %s" % [body.collision_layer, COLLISION_LAYER])
talk("collision mask: %s -> %s" % [body.collision_mask, COLLISION_MASK])
body.collision_layer = COLLISION_LAYER
body.collision_mask = COLLISION_MASK
func get_dir_children(path: String) -> Array:
talk("Getting objects in %s" % path)
var dir = Directory.new()
var objectsPaths = []
if dir.open(path) == OK:
dir.list_dir_begin()
var file_name = dir.get_next()
while file_name != "":
if not dir.current_is_dir():
objectsPaths.append(path + file_name)
file_name = dir.get_next()
else:
talk("An error occurred when trying to access the path.")
return objectsPaths
func talk(message) -> void:
var is_verbose = verbose_input.pressed
if is_verbose:
print(message)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment