This is a video of the Eiffel Tower that I made to appear by designating a frame myself. but I want to frame automatically in the order of object number or creation so that they appear in the video. So, I want to make a video that appears in order, one by one, block by block like the Minecraft building videos. Is there a way to use an animation node or another way?
I thought at first about achieving this using Drivers but it's too difficult to clone the driver to each object visibility without resorting to scripting - so I figured why not just use scripting anyway.
I'll vary by height as it's simpler - but you could tweak the code to change the order of visibility to use some other property (could assign a property to each object or use the position in the list of objects (which will relate to the order of creation).
Start by creating a new Scene custom property named 'Height' and set it to be able to vary over a suitable range - this should be keyframed to reveal the objects.
Next, open a Text Editor window and paste the following code in a new text block named 'hideshow.py' :
#Hide objects above some threshold import bpy def frame_change_hideshow_objects(scene): height = bpy.context.scene["Height"] for obj in bpy.data.objects: if obj.location > height: if obj.hide_viewport != True: obj.hide_viewport = True obj.hide_render = True else: if obj.hide_viewport != False: obj.hide_viewport = False obj.hide_render = False bpy.app.handlers.frame_change_pre.append(frame_change_hideshow_objects)
Click the 'Run' button (a 'play' button in the header) to execute the code and it will install a “handler” to run on each frame change. Each time it runs it compares the value of the scene property ‘Height’ with the Z coordinate of each object in turn, flipping the visibility based on the height if it has changed.
Now keyframe the new 'Height' scene property to vary over your range. Play the animation and your objects will show/hide based on whether they are above or below the 'Height' :
In order to use the image id instead of Height, rename the scene property to something appropriate (eg, 'RevealID') and amend the code to compare that with the point in the list of each object (ie, the number of times around the loop) :
#Hide objects above some threshold import bpy def frame_change_hideshow_objects(scene): revealId = bpy.context.scene["RevealID"] objcount = 0 for obj in bpy.data.objects: objcount+=1 if objcount > revealId: if obj.hide_viewport != True: obj.hide_viewport = True obj.hide_render = True else: if obj.hide_viewport != False: obj.hide_viewport = False obj.hide_render = False bpy.app.handlers.frame_change_pre.append(frame_change_hideshow_objects)
In my example this produced the following result. Note that the objects were created using 'Grid fill' particles so they are created in an uncontrolled sequence (this is why basing on height was simpler!!) :
For better results you would need to take more care in the creation order of the objects than I did - or re-sequence the objects in some way. Alternatively, use a method of revealing the objects that isn't based on the creation order such as by height as described above, by amending the code.