Editing Skeleton3D rest pose - Godot 3 -> Godot 4

Godot Version

4.3 Stable

Question

In Godot 3.4 I had a method to edit my skeleton - not it’s animated poses, but it’s rest or base pose. When I made my character taller I could edit the skeleton and the animations would still work.

E.g. same mesh, different height, works fine

In Godot 4 my code appears to do nothing.

Does anyone know how to achieve this? I make the character taller with blend shapes, but currently I’m creating a monster if I use any non-rest pose.

Extra info:

This is my code that doesn’t work in Godot 4 - the only changes in updating it from 3 were:

-BoneAttachment → BoneAttachment3D

-Spatial →Node3D

-Added ‘boneAttachment.on_skeleton_update()’, as I noticed BoneAttachment3D didn’t get it’s position when first attached.

func updateSkeleton():
	anim.play("apose")#same as rest, no posing at all
	anim.advance(1)
	var numBones = skeleton.get_bone_count()
	for boneToUpdate in numBones:
		var boneName = skeleton.get_bone_name(boneToUpdate)
		if boneName == "Base":
			pass
		else:
			var jointName = getJointNameFromBoneName(boneName)
			var desiredLocation = get_node("bonesGLB").getBlendShapedPositionOfBone(jointName)
			moveBoneToGlobal(desiredLocation,boneToUpdate)
	fixSkins()
	anim.play("apose")#set it back to previous animation if desired
	anim.advance(1)
func moveBoneToGlobal(pos,boneNum):
	var parentNum = skeleton.get_bone_parent(boneNum)
	if parentNum==-1:#no parent, root bone, never moves in this
		pass
	else:
		var parentBoneAttachment = BoneAttachment3D.new()
		parentBoneAttachment.bone_name = skeleton.get_bone_name(parentNum)
		skeleton.add_child(parentBoneAttachment)
		parentBoneAttachment.on_skeleton_update()#this makes it updates its position to the skeleton
		var boneTrans = skeleton.get_bone_rest(boneNum)
		var s = Node3D.new()
		s.transform = boneTrans
		parentBoneAttachment.add_child(s)
		s.global_transform.origin = pos
		skeleton.set_bone_rest(boneNum,s.transform)
		parentBoneAttachment.remove_child(s)
		s.queue_free()
		skeleton.remove_child(parentBoneAttachment)
		parentBoneAttachment.queue_free()
func fixSkins():
	var skin = base.skin#base = MeshInstance3D
	var numBinds = skin.get_bind_count()
	for n in range(numBinds):
		var bindName = skin.get_bind_name(n)
		var boneIndexInSkel = skeleton.find_bone(bindName)
		var gp = skeleton.get_bone_global_pose(boneIndexInSkel)
		var gpi = gp.inverse()
		skin.set_bind_pose(n,gpi)

This was a struggle for me to make in Godot 3, I ended up using BoneAttachments to calculate the transform for me. In Godot 3 I was editing the mesh directly, not using blend shapes. I’m hoping that won’t matter.

I have tested extensively to check the ‘desiredPosition’ is correct, and have confirmed it using MeshInstances:


(Tall character with spheres placed at the desired bone locations)

I am using a similar technique to view the results of the bones, this time red cubes, but they don’t move:

EDIT: I have fixed it, to some degree. The fixSkins method was incorrect, and I have replaced it with the one by Zechi79 (which amusingly is to some degree based on mine that won’t work) on this page:
https://www.reddit.com/r/godot/comments/ta3cmr/how_to_move_bone_to_a_specific_point_in_world/

I confirmed this one worked by importing a second ‘pre-altered’ skeleton and switching to it, then running this to fix the skin file.

The second thing is that you have to run fixSkins() after every individual bone change, before you do the next bone.

Finally, animations. They’re broken. I have no idea how to fix them. I’m only using rotation for my animations(no location/scale changes) so I manually looped through my animations before any editing, saved all rotations (get_bone_pose_rotation), saved them, then created a method to apply all these rotations (set_bone_pose_rotation). Important to remember to use this method to set the “default” animation before updating the skeleton (e.g. t-pose, or whatever you use).

(On this forum I can’t seem to edit my post, it says that new users can’t have more than 1 image or something, despite letting my post originally have more, so I’m editing with a reply)