@tool class_name BodyFollowsHead extends SkeletonModifier3D @export_enum(" ") var head: String @export_enum(" ") var hips: String func _validate_property(property: Dictionary) -> void: if property.name == "head": var skeleton: Skeleton3D = get_skeleton() if skeleton: property.hint = PROPERTY_HINT_ENUM property.hint_string = skeleton.get_concatenated_bone_names() if property.name == "hips": var skeleton: Skeleton3D = get_skeleton() if skeleton: property.hint = PROPERTY_HINT_ENUM property.hint_string = skeleton.get_concatenated_bone_names() func _process_modification() -> void: var skeleton: Skeleton3D = get_skeleton() if !skeleton: return var head_idx: int = skeleton.find_bone(head) var head_pose: Transform3D = skeleton.get_bone_global_pose(head_idx) var hips_idx: int = skeleton.find_bone(hips) var hips_pose: Transform3D = skeleton.get_bone_global_pose(hips_idx) var new_basis: Basis new_basis.y = Vector3.UP # #var hips_basis: Basis = hips_pose.basis #var head_basis: Basis = head_pose.basis #var head_yaw = head_basis.get_euler().y # Y-axis rotation in radians #var hips_euler = hips_basis.get_euler() #var hips_yaw = hips_euler.x #var new_yaw = lerp_angle(hips_yaw, head_yaw, 100) #hips_euler.x = new_yaw #hips_basis = Basis.from_euler(hips_euler) # Apply the new transform back to the skeleton hips_pose.basis = hips_basis skeleton.set_bone_global_pose(hips_idx, hips_pose)