I understand that it's possible to keyframe visibility, and that might have to be at least part of the solution. However, I intend to create many objects at once, with a script to generate them, so I can't think how to apply visibility keyframes, when I'd have so many objects which initially don't exist.

If it helps, here's the (messy) code I'm working with:

import bpy

CoList = []

def DeleteExisting():


def Create_List(Width):
    for x in range(0,Width):
    for i in CoList:
        x = i[0]
        for y in range(0,Width):
    return CoList

def Generate_Cubes(CoList):
    for x in CoList:
        for y in x:
            X_Value = y[0]
            Y_Value = y[1]
            while type(X_Value) == list:
                if type(X_Value) == list:
                    X_Value = X_Value[0]
                if type(Y_Value) == list:
                    Y_Value = Y_Value[0]
            bpy.ops.mesh.primitive_cube_add(view_align=False, enter_editmode=False, location=(X_Value, Y_Value, 0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
            bpy.ops.transform.resize(value=(0.25, 0.25, 0.25), constraint_axis=(False, False, False), constraint_orientation='GLOBAL', mirror=False, proportional='DISABLED', proportional_edit_falloff='SMOOTH', proportional_size=1)

for X in range(1,6):
    bpy.context.scene.frame_current = X
    Width = X+2
    CoList = Create_List(Width)

This creates a grid of cubes, which looks like this:

And it also advances the current frame, however once an object is created, it exists on all frames, regardless of any keyframes that I know of. So how would I implement this so that objects only exist on the frame which they are created on?


2 Answers 2


Driver based method,

driving the hide property, simply hiding a cube if its "visframe" custom property is greater than the frame number. Creates a 10 x 10 grid of cubes where only one is visible on frame 1, 2 On frame 2, ... 100 on frame 100. Drive the hide_render property to render.

import bpy
context = bpy.context
scene = context.scene
cube = context.active_object
cube.scale *= 0.25

for i in range(10):    
    x = 2 * i    
    for j in range(10):

        cube["visframe"] = 10 * i + j        
        # add a driver
        fcurve = cube.driver_add("hide_render")
        driver = fcurve.driver
        var = driver.variables.new()
        var.name = "vis"
        var.targets[0].id = cube
        var.targets[0].data_path = '["visframe"]'
        # scene.frame_current is defined as frame to driver namespace
        driver.expression = "vis >= frame" # show if cube["visframe"] > frame
        y = 2 * j
        cube.location.xy = (x, y)        
        cube = cube.copy()

Each object has two properties called hide and hide_render - the first is viewport visibility and the second is render visibility.

To use python to set a keyframe for a property you set the value, then use keyframe_insert(data_path, frame=f) to keyframe it. So if you only want to object visible on one frame, you make it visible and set a keyframe on the relevant frame, then hide it and add a keyframe for the previous and next frame.

import bpy

# clear any existing objects
for o in bpy.data.objects:
    o.hide = False

grid_size = 7
# the default cube is 2 units wide, add another .2 for gap
spacing = 2.2

for x in range(grid_size):
    for y in range(grid_size):
        f = (x*grid_size) + y
        bpy.ops.mesh.primitive_cube_add (location=(x*spacing, y*spacing, 0))
        obj = bpy.context.active_object
        # key as visible on the current frame
        # hide it
        obj.hide = True
        obj.hide_render = True
        # key as hidden on the previous frame
        # key as hidden on the next frame

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.