Material change per frame

Hello, I’m trying to change material of an object every frame, but i want it to work only for an active object but my script changes it for every object , how can I fix it?

# Import the bpy module
import bpy

# Get a reference to the active object in the scene
obj = bpy.context.view_layer.objects.active

# Create an empty list to store the materials
materials = []

# Iterate over all of the materials assigned to the object
for material_slot in obj.material_slots:
    # Add each material to the list
    materials.append(material_slot.material)

# Set the current index to 0
current_index = 0

# This function will be called after every frame update
def switch_material(scene):
    global current_index

    # Switch to the next material in the list
    current_index = (current_index + 1) % len(materials)
    obj.active_material = materials[current_index]

# Register the function to be called after every frame
bpy.app.handlers.frame_change_post.append(switch_material)

P.S this script was created by openai, I have zero knowledge of python

Well that’s horrifying :thinking: what a disturbing result of Blender add-on code being open source, AI bots that harvest and steal it freely… but I digress.

Change your “obj =“ line to be

obj = bpy.data.objects[‘Cube’]

Where Cube is the name of the object you want this to affect

3 Likes

Thanks! I gave OpenAi the modified code and asked it to make it for mutiple objects, and it gave me aworking one! cool

# Import the bpy module
import bpy

# Define a list of objects to cycle the materials for
object_names = ['Object1', 'Object2', 'Object3']

# Create a dictionary to store the materials for each object
materials = {}

# Iterate over the objects in the list
for obj_name in object_names:
    # Get a reference to the object
    obj = bpy.data.objects[obj_name]

    # Create an empty list to store the materials for this object
    materials[obj_name] = []

    # Iterate over all of the materials assigned to the object
    for material_slot in obj.material_slots:
        # Add each material to the list
        materials[obj_name].append(material_slot.material)

# Set the current index to 0 for each object
current_indexes = {}
for obj_name in object_names:
    current_indexes[obj_name] = 0

# This function will be called after every frame update
def switch_material(scene):
    global materials, current_indexes

    # Iterate over the objects in the list
    for obj_name in object_names:
        # Get the current index for this object
        current_index = current_indexes[obj_name]

        # Get a reference to the object
        obj = bpy.data.objects[obj_name]

        # Switch to the next material in the list
        current_index = (current_index + 1) % len(materials[obj_name])
        obj.active_material = materials[obj_name][current_index]

        # Update the current index for this object
        current_indexes[obj_name] = current_index

# Register the function to be called after every frame
bpy.app.handlers.frame_change_post.append(switch_material)
1 Like

Awesome, have you registered with a paid plan to use it? I think about trying it myself. :slight_smile:

It’s free for now as a beta test, but I’ll definitely subscribe when it becomes paid. Just google ChatGPT

Great, thanks for the tip. :slight_smile:

Welp, I can already predict a dip in overall code quality in the next few years if this AI retroactively learns from code it generated… :sweat_smile:

Impressive feat nonetheless ! I would just like it to throttle down on comments a little bit, python doesn’t need that much to be legible…

Here’s another solution which won’t mangle your object materials and won’t overload your RAM if you have thousands of objects. :slight_smile:

import bpy

object_names = ['Object1', 'Object2', 'Object3']

def update_materials_after_frame_change(scene):
    for name in object_names:
        obj = scene.objects[name]
        materials = obj.data.materials[:]
        for i, material_slot in enumerate(obj.material_slots):
            material_slot.material = materials[(i + 1) % len(materials)]

bpy.app.handlers.frame_change_post.append(update_materials_after_frame_change)

Animation3

1 Like

thank you! you could also ask it to simplify the code afterwards, but i don’t know how good the result is. You should try it with your code or something maybe it will be useful to you.