Rotating 2D bones from a script

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Grant Forrest

New to Godot. I have a 2D Skeleton rigged up, basically following the Cutout Animation tutorial.

I’m interested in doing some procedural animation. So I implemented a basic 2-bone algorithm based on some internet tutorials. Whether or not it works yet on a mathematical level, I’m unsure, but here it is:

extends Skeleton2D

onready var left_arm_upper = $hip/waist/chest/arm_upper_left
onready var left_arm_lower = $hip/waist/chest/arm_upper_left/arm_lower_left

func _process(_delta):
	animate_arm(left_arm_upper, left_arm_lower, get_global_mouse_position())

func animate_arm(arm_upper: Bone2D, arm_lower: Bone2D, target_pos: Vector2):
	var offset = target_pos - global_position
	var distance = offset.length()

	var joint_angle_0
	var joint_angle_1
	var atan_val = atan2(offset.y, offset.x)
	var length_0 = arm_upper.default_length
	var length_1 = arm_lower.default_length
	# it's too far away
	if length_0 + length_1 < distance:
		joint_angle_0 = atan_val
		joint_angle_1 = 0
		var angle_0 = law_of_cos(distance, length_0, length_1)
		var angle_1 = law_of_cos(length_1, length_0, distance)
		joint_angle_0 = atan_val - angle_0
		joint_angle_1 = PI - angle_1

	arm_upper.rotation = joint_angle_0
	arm_lower.rotation = joint_angle_1

func law_of_cos(a, b, c):
	if 2 * a * b == 0:
		return 0
	return acos( (a * a + b * b - c * c) / (2 * a * b) )

But although I can debug the script to see that at least the angle values are changing, nothing moves in the scene.

Things I’ve tried:

  1. Removed IK chain on the arms
  2. Removed the animator I also had on the root node
  3. Tried using arm_upper.transform = arm_upper.transform.rotated(joint_angle_0)
  4. Copied the script to a set of basic nodes (not bones) in the same structure and saw that the rotation does appear to be applied to them

So, any ideas? Can you rotate bones from scripts? I’d really like to keep the Skeleton, even if I do all procedural animation - it’s nice to have polygons for the sprites and deform them.

Do people do procedural animation in Godot? How should I be moving / rotating the bones from scripts?

:bust_in_silhouette: Reply From: Grant Forrest

I overlooked a major mistake in my scene setup - I had recently renamed my skeleton node, and I had failed to update the skeleton references on the Polygon2D nodes associated with the bones. I should have realized that even moving my bones in the editor was not updating my pose!

Once I corrected the Skeleton references, applying simple rotation works! I still have no IK chains and no animator applied. I’m not sure if restoring those things will affect the outcome, but I don’t need them right now so I will keep going without them.

Perhaps the code from my question will be a good starting point for others doing procedural animation in 2D. It’s actually not correct (the movement is off), but it does at least respond to user input and rotate the bones.