Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
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