import bpy from random import random from mathutils import Matrix, Quaternion ob = bpy.data.objects['Sphere'] frame_number = 0 max_dist = 0.5 #start_location = ob.location.copy() start_location = (1.6766993999481201, 0.3146645724773407, -1.3483989238739014) finger_grab_bones = ["index_3", "middle_3", "ring_3", "pinky_3"] thumb_rot_bone = "thumb_3" def grab_movement(open): # Todo: # select the 4 base finger bones # Then: # To rotate around local axis (will cause to grab) # Then do the same with thumb, but only around local Z axis! bpy.ops.object.mode_set(mode='OBJECT') bpy.ops.object.select_all(action='DESELECT') # Deselect all objects arm = bpy.data.objects['Armature'] bpy.context.view_layer.objects.active = arm # Make the Armature the active object bpy.ops.object.mode_set(mode='POSE') # Rotate all fingers if open: angle = -0.8 else: angle = 0.8 # Deselect all fingers for bone in arm.pose.bones: # Deselect all selected bones bone.bone.select = False # Rotate fingers for name in finger_grab_bones: bone = arm.pose.bones.get(name) # Bones need to be selected when adding keyframes, otherwise blender will throw an error: # https://blender.stackexchange.com/questions/1828/what-constitutes-a-context-in-pose-mode bone.bone.select = True # rotate axis = bone.x_axis bone.rotation_quaternion = bone.rotation_quaternion @ Quaternion(axis, angle) # bone.matrix = bone.matrix @ Matrix.Rotation(-angle, 4, axis) # Add keyframe bpy.ops.anim.keying_set_active_set(type='Rotation') bpy.ops.anim.keyframe_insert(type='Rotation') # Now rotate the thumb too for bone in arm.pose.bones: # Deselect all selected bones bone.bone.select = False bone = arm.pose.bones.get(thumb_rot_bone).bone if bone: bone.select = True bpy.ops.transform.rotate(value=angle, orient_axis='Z', orient_type='LOCAL') bpy.ops.anim.keyframe_insert(type='Rotation') # Script start open = False #if len(bpy.data.scenes['Scene'].keying_sets) == 0: # # Add new keying set # bpy.ops.anim.keying_set_add() # # Activate keying set # bpy.ops.anim.keying_set_active_set() for i in range(50): x = random()*max_dist y = random()*max_dist z = random()*max_dist bpy.context.scene.frame_set(frame_number) ob.location = ( start_location[0] + x, start_location[1] + y, start_location[2] + z ) ob.keyframe_insert(data_path='location', index=-1) grab_movement(open) open = not open frame_number += 20