Created
December 30, 2024 10:25
-
-
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.
This file contains 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
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
In this case, the turret's collision sphere is a Deconstructible, and it took the turret with it.