1
$\begingroup$

I'm trying to write a Blender Python script that moves three bones in an armature based on columns in a CSV file. I’ve gotten it to consistently move one bone, but when I try to do more than that one, the script will only move one of the bones. It does seem to create keyframes for the rest.

The variables are as follows:

Cnt = a count variable

Fcnt = Frame count, this is the current frame, and has other uses earlier in the code

Bone_1, Bone_2, and Bone_3 : the bones in the armature

col1, col2, and col3: columns in the CSV file that correspond to the locations for Bone_1, Bone_2, and Bone_3.

Additional context: At this point, the armature is already selected and blender enters pose mode.

Code begins:

for row in col1:
     bpy.context.scene.frame_current = Fcnt


     C1 = col1[CnT]
     C2 = col2[CnT]
     C3 = col3[CnT]


     # Bone_1:

     # Deselect All:
     bpy.ops.pose.select_all(action='DESELECT')

     # Select bone to move:
     Bone_1.select= True

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")

     # Move Bone:
     bpy.context.active_pose_bone.location[1] = C1

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")

     # Bone_2
        
     # Deselect All:
     bpy.ops.pose.select_all(action='DESELECT')

     # Select bone to move:
     Bone_2.select= True

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")

     # Move Bone:
     bpy.context.active_pose_bone.location[1] = C2

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")

     # Bone_3:
        
     # Deselect All:
     bpy.ops.pose.select_all(action='DESELECT')

     # Select bone to move:
     Bone_3.select= True

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")

     # Move Bone:
     bpy.context.active_pose_bone.location[1] = C3

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")

     bpy.ops.pose.select_all(action='DESELECT')    

     CnT += 1
     Fcnt += 2
$\endgroup$
0

1 Answer 1

0
$\begingroup$

The bone you want to move is the active bone, not the selected bone.

# Move Bone:
bpy.context.active_pose_bone.location[1] = Cn

Therefore, you need to use
# Set active bone to move:
bpy.context.object.data.bones.active = Bone_n

instead of

# Select bone to move:
Bone_n.select= True


Then, it is better to delete the first Add Keyframe.

# Add Keyframe:
bpy.ops.anim.keyframe_insert_by_name(type="Location")

     # Bone_1:

     # Deselect All:
     bpy.ops.pose.select_all(action='DESELECT')

     # Set active bone to move:
     bpy.context.object.data.bones.active = Bone_1

     # Move Bone:
     bpy.context.active_pose_bone.location[1] = C1

     # Add Keyframe:
     bpy.ops.anim.keyframe_insert_by_name(type="Location")
$\endgroup$
3
  • $\begingroup$ Thank you! I got it working with a different solution but you definitely put me on the right track. I'd like to understand your solution though as I'm still new at this and I couldn't get it to work exactly how you suggested. In my solution, I sidestepped selecting the bones and changed their locations like this: Bone_1.location[1] = C1 Bone_2.location[1] = C2 Bone_3.location[1] = C3 Then selected all and added the keyframe. In the bpy.context.object.data.bones.active = Bone_1, do I need to add the name of the Armature in brackets or something? I couldn't get this to work. $\endgroup$ Jul 26, 2023 at 6:04
  • $\begingroup$ @Bobby J. Bee As long as type(Bone_1) is <class 'bpy_types.Bone'>, you don't need to add anything to that snippet. Note that the keyframe_insert_by_name function inserts keyframes into the active bone as well as the selected bones. $\endgroup$
    – tetii
    Jul 26, 2023 at 8:23
  • $\begingroup$ Thank you for the clarification. You've been a huge help! $\endgroup$ Aug 1, 2023 at 2:41

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .