Skip to content

Instantly share code, notes, and snippets.

@jamonholmgren
Created December 30, 2024 10:25
Show Gist options
  • Save jamonholmgren/187cf7d5ca8b6369bc34425225232c18 to your computer and use it in GitHub Desktop.
Save jamonholmgren/187cf7d5ca8b6369bc34425225232c18 to your computer and use it in GitHub Desktop.
Godot 4.3 Deconstructible subclass for CollisionShape3D. Lets you deconstruct subnodes from RigidBody3D's (etc) and have them lifelessly fall to the ground.
# Allows a model to be deconstructed into various parts with physics
# Attached to a CollisionShape3D, which has a reference to a node that it'll
# deconstruct with.
# Just set this as the script of any CollisionShape3Ds that you want to do this
# with and then edit the nodes in your editor
class_name Deconstructible extends CollisionShape3D
# Any nodes you want removed from the original parent and
# added to the new RigidBody3D parent
@export var parts: Array[Node3D] = []
# This is subtracted from the original collision parent's mass
# and set as the new RigidBody3D parent's mass
@export var parts_mass: float = 500.0
var deconstructed := false
func deconstruct():
if deconstructed: return # avoid multiple calls
deconstructed = true
# Original parent of this node
var my_original_parent = get_parent()
var my_original_transform = global_transform
# Create a new RigidBody3D node for everything to be added to
var new_body := RigidBody3D.new()
new_body.name = "Deconstructed" + name
# Add it to the scene tree
get_tree().root.add_child(new_body)
# Position it in the shape's original position
new_body.global_transform = my_original_transform
# Add all the parts to the collision parent
for part in parts:
var orig = part.global_transform
part.get_parent().remove_child(part)
new_body.add_child(part)
part.global_transform = orig
# Add the original shape to the collision parent
my_original_parent.remove_child(self)
new_body.add_child(self)
# Position it back to its original position
global_transform = my_original_transform
new_body.process_mode = Node.PROCESS_MODE_INHERIT
new_body.set_physics_process(true)
new_body.collision_layer = my_original_parent.collision_layer
new_body.collision_mask = my_original_parent.collision_mask
# Set the new mass, subtracting from the original parent's mass
new_body.mass = parts_mass
my_original_parent.mass -= parts_mass
# Avoid massive spinning
new_body.angular_damp = 2.5
@jamonholmgren
Copy link
Author

In this case, the turret's collision sphere is a Deconstructible, and it took the turret with it.

Godot 2024-12-30 01 56 37

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment