How do actions with multiple objects work?

I have a model rigged and animated with armature, and it works just fine.
Now I want to alter some mesh properties during these actions, like changing transparency and UV offset. But as far as I can see it works very odd.

The main issue is that when I keyframe mesh or shader node attribute these changes affect all existing animations.

Here is a sample code:

import bpy

if 'Cube' not in bpy.data.objects:
    bpy.ops.mesh.primitive_cube_add()
cube = bpy.data.objects['Cube']

# Create move actions
cube.animation_data_create()

# Move along x axis
move_action_x = bpy.data.actions.new(name='move_x')
cube.animation_data.action = move_action_x
cube.location[0] = 0
cube.keyframe_insert('location', index=0, frame=0)
cube.location[0] = 10
cube.keyframe_insert('location', index=0, frame=20)

# Move along y axis
move_action_y = bpy.data.actions.new(name='move_y')
cube.animation_data.action = move_action_y
cube.location[1] = 0
cube.keyframe_insert('location', index=1, frame=0)
cube.location[1] = 10
cube.keyframe_insert('location', index=1, frame=30)

# Create material
mat = cube.data.materials[0]
mat.use_nodes = True
links = mat.node_tree.links
node = mat.node_tree.nodes.new('ShaderNodeMix')
node.data_type = 'RGBA'
node.inputs['A'].default_value = 1, 0, 0, 0
node.inputs['B'].default_value = 0, 0, 1, 0
links.new(node.outputs['Result'], mat.node_tree.nodes['Principled BSDF'].inputs['Base Color'])

# Create color_change action
color_action = bpy.data.actions.new(name='color')
mat.node_tree.animation_data_create()
mat.node_tree.animation_data.action = color_action
node.inputs[0].default_value = 0
mat.node_tree.keyframe_insert('nodes[2].inputs[0].default_value', frame=0)
node.inputs[0].default_value = 1
mat.node_tree.keyframe_insert('nodes[2].inputs[0].default_value', frame=10)

I can get the same result with manual editing, but the script is easier to share.

In this example, I can only find two move actions in Animation Editor, but both of them also modify color.

Here is what the script result looks like, with only 2 available actions and changing color:

My best guess is that’s because color change uses a different object (mat.node_tree.animation_data instead of cube.animation_data) and it confuses Blender.

Is there any way to prevent color changes from leaking into other actions?
Is it possible to animate different objects, like armature, meshes, and shader nodes inside the same action?

Result of the script: move_and_color.blend (922.4 KB)

You can set a custom property on the object, and then reference it in the material.
move_and_color_prop.blend (122.5 KB)

Then to use it in an armature, you can create a matching custom property on a bone in Pose Mode on the armature. Hook that bone property to the object property with a driver.

That way you can keyframe the property on the bone, and it all stays within the same Action on the armature object.

1 Like

Thanks a lot, it works.
It’s a shame I cannot simply keyframe everything. Editing a bunch of custom properties is quite awkward.

Yeah. It can get a bit tedious chaining it all together.

You can also set the type of a custom property to be a color. Setting up the drivers for that is a bit long-winded, as it needs a driver for each color channel (R, G, and B).