1
$\begingroup$

I have a python script that runs through Blender and I use it to procedurally animate two figures. I gave the models animation actions which work in Blender, but in the python script how do I tell the objects to add their action to the animation at specific frames?

scene = bpy.context.scene
scene.frame_set(10) #go to frame 10

#assign animation action to object
bpy.data.objects[0].animation_data.action = bpy.data.actions[0]

#play that animation Action on frame 10
help meeeee!

#render the video
bpy.ops.render.render(animation=True, write_still=True)

After help from Sighthound here is the final part of the script that now works, commented to explain why the other stuff needed to be added

#define starting frame
frame = bpy.data.scenes[0].frame_start = 1 

#loop through arrays that hold information for which frame to play the action strips on
for data in Datas: 
    frame = data['FRAME']

    #set current frame in blender to the frame called for in data array
    bpy.context.scene.frame_set(frame) 
    
    #loop through keys that are nested in data array
    for key in data['KEYS']: 

        #if data calls for action_01 to play on this frame...
        if(key == "action_01"): 
            #add a new track
            track = bpy.context.active_object.animation_data.nla_tracks.new() 
            
            #name the upcoming new strip with frame appended to keep it unique
            newStripName = 'action_01_' + str(frame) 

            #add new strip to the new track with the correct action
            newStrip = track.strips.new(newStripName, frame, bpy.data.actions['action_01']) 

            #must set the new strips extrapolation property to none so that all the strips will play in the animation instead of just the top one
            bpy.context.object.animation_data.nla_tracks[track.name].strips[newStrip.name].extrapolation = 'NOTHING' 
$\endgroup$
0
0
$\begingroup$

I think Strips in the NLA are more suitable for your purpose than Actions.

Actions are containers for FCurves/keyframes.

Strips on the other hand are containers for Actions. Strips can be moved comfortably to the desired position on the timeline.

In the Action editor "Push down" you action as a new strip to the NLA editor. In the Nla editor you can drag the newly added strip anywhere on the timeline.

From here on you could toggle and move your strips on the timeline with Python. Here's a quick sketch:

for track in bpy.context.active_object.animation_data.nla_tracks:
    for strip in track.strips:
        if strip.action == bpy.data.actions[0]:
            start_frame = 10
            strip.frame_start = start_frame
            strip.frame_end = (
                strip.action_frame_end - strip.action_frame_start + start_frame
            )

To add an action as a strip to the Nla, use:

start_frame = 10
strip = track.strips.new(bpy.data.actions[0].name, start_frame, bpy.data.actions[0])

Relevant API Docs:

https://docs.blender.org/api/current/bpy.types.NlaTrack.html?highlight=nlatrack#bpy.types.NlaTrack

https://docs.blender.org/api/current/bpy.types.NlaStrips.html#bpy.types.NlaStrips

https://docs.blender.org/api/current/bpy.types.NlaStrip.html#bpy.types.NlaStrip

$\endgroup$
1
  • $\begingroup$ Thanks Sighthound, your info was what I was looking for. I had to go through a few more steps to get it working so I'll add the finished part of working script in case it might help out anyone else $\endgroup$ Dec 28 '20 at 0:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.