4
$\begingroup$

I have a scene with multiple objects, each potentially using multiple actions.

I want to export the keyframes for each action with my own Python script, but only for the object that uses that action.

I see that each action has a user count, but I can't figure out how it keeps track of which objects use it. I know how to export the keyframes, but I can't find a way to associate actions with only certain objects.

Is this even possible? If not, how do other people deal with this problem?

$\endgroup$
4
$\begingroup$

Actions are globally stored in bpy.data.actions, regardless of scenes.

Every object can reference one and only one action (Object.animation_data.action). Thus, you can't know which actions are made for / compatible with which objects without extra work on the user oder coder side.

  • User-based solution:
    Let the user specify which actions are supposed to be exported for which objects, either in a Panel in the export file selector or for every object in the object tab - both are not ideal. The former needs to be re-done every time (unless presets are used), in the latter renaming actions will break it.

  • Programmatic solution:
    Check all FCurves' data_paths and see if these properties are available for your object type. This should work reliable to distinguish Armature actions from other more generic ones, as the data paths start with 'pose.bones' for Pose actions.

$\endgroup$
  • $\begingroup$ I went with a combination of those two things. $\endgroup$ – KTC Jul 27 '14 at 18:51
4
$\begingroup$

It's also actually possible to have multiple actions associated with a single object via the NLA editor and the tracks therein. In my exporter, I am using this and muting the NLA tracks for animations that are not currently active.

Here's the routine I use to gather all of the actions from the object and all of it's NLA tracks:

def get_all_actions(obj):
  """Retrieve all actions given a blender object. Includes NLA-actions"""
  if obj.animation_data:
    if obj.animation_data.action:
      yield obj.animation_data.action
    for track in obj.animation_data.nla_tracks:
      for strip in track.strips:
        yield strip.action
$\endgroup$
1
$\begingroup$

Another solution might be to name the action using the name of the target object.

For example, if you want multiple actions for an object named Cube, then name your actions Cube_Action1, Cube_Action2, etc... Or you might use Action1[Cube], Jump[Cube] etc...

Don't name it Cube.001 because that would clash with a copied object of that name.

In your export script, look through the actions, and then associate them with the object of the same name.

$\endgroup$

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.