Moving node out of Skeleton3D while preserving global_transform

Godot Version

4.3.1 beta


Cannot figure this out.

End goal: I have a robot that drops an arm. The arm is then able to be moved around by the player.

Example of behavior I’m trying to accomplish through moving nodes out of their local tree:

Only able to get this to work by instatiating a new scene and switching it out, not by moving the node to root. Was trying to make something more dynamic and less time consuming than parting out limbs on every “breakable” character into scenes and instatiating them individually.

What I’m trying via the “move nodes” method:

  • Store global transform of arm
  • Duplicate as new arm
  • Hide original arm
  • Add new arm to get_tree().root
  • Apply global_transform to new arm

What happens:
Transform data not applied properly when adding to get_tree().root or any node outside the Skeleton3D. So possible this is unique to Skeleton3D and requires some extra logic to convert the global transform. But don’t know if there’s a remedy for this / how to correct other than manually tweaking it…

Works perfectly fine when I try adding the child to the original arm’s parent Skeleton3D. Looks great. Problem is, it needs to be detached so it doesn’t move with the owner of this skeleton, a CharacterBody3D. So that’s why I’m adding it to get_tree().root.

I have tried multiplying transforms up the tree manually including using the global_bone_pose (which is relative to the Skeleton3D not a true global value). No luck.


# Sample code

func hide_part(part: MeshInstance3D):
	# Duplicate mesh
	var xform = part.global_transform
	var mesh: MeshInstance3D = part.duplicate()
	# Transform looks good, but doesn't achieve end goal
	# part.get_parent().add_child(mesh)
	# mesh.global_transform = xform
	# Creates super tiny part with wonky transform
	mesh.global_transform = xform