Swap out materials with a frame change handler
As a proof of concept, here is a handler that simply swaps out all of the materials of an object when frame is withing a range defined by a custom property
A dictionary of each scene objects name to material names is created and printed (xxx)
materials = {o.name : [
s.material.name if s.material else "None"
for s in o.material_slots
] for o in scene.objects
}
print(materials)
for my very simple example scene has 3 objects, the lamp and cam have no materials, the cube has 3 slots set to, in order, "Material", "Red" and "Red". If slot is empty it is given the name "None".
{'Cube': ['Material', 'Red', 'Red'], 'Lamp': [], 'Camera': []}
so instead could replace the generation (xxx) with (for my example)
materials = {'Cube': ['Material', 'Red', 'Red'], 'Lamp': [], 'Camera': []}
The handler script. Creates the dict and on a frame change if any object in scene has custom property "highlight" and the frame is in the range defined by property a highlight material is used for all materials of that object.
The script only need be run once. As with all scripts make sure you save your file first.
import bpy
context = bpy.context
scene = context.scene
scene.frame_set(0)
highlightmat = "Red"
materials = {o.name : [
s.material.name if s.material else "None"
for s in o.material_slots
] for o in scene.objects
}
print(materials)
def frame_change(scene, depsgraph):
iframe = int(scene.frame_current)
for ob in scene.objects:
highlight = ob.get("highlight")
if highlight and iframe in range(*highlight):
for s in ob.material_slots:
s.material = bpy.data.materials.get(highlightmat)
elif highlight or not iframe:
for key, s in zip(materials[ob.name], ob.material_slots):
if s and key:
s.material = bpy.data.materials.get(key)
bpy.app.handlers.frame_change_post.clear()
bpy.app.handlers.frame_change_post.append(frame_change)
Frame 0 is used as a default reset. Suggest don't include 0 when defining object highlight ranges.
Set the object highlight range
To highlight the current context object from frame 2 to 30, go to python console and type in
C.object["highlight"] = [2, 30]
(Not sure how to do the list with UI)
If you know the names of all your objects, could also hard code this into the script above. Eg to have "Elvis" highlighted frames 20 to 444
bpy.data.objects["Elvis"]["highlight"] = [20, 444]
then with the handler active playing animation will cause all materials to swap to highlightmat
which I have set to use the material named "Red", change to suit
highlightmat = "Red"
EDIT
In as much as can swap the materials as shown above, consider setup materials to use the object info node utilizing the pass index or object color to flag and animate a highlight.
Control object emission strength (not material)
Same Material with different key frames