1
$\begingroup$

I have several Parent objects that each have a lot of child objects. I need to key frame showing/hiding the various different stacks of objects at different points without it becoming too tedious. Ideally, i'd like it if I could set my child objects to share the show/hidden status of the parent object. Is this possible?

Alternatively, is there a way to keyframe the show/hide of a whole selection of objects at once?

$\endgroup$
3
  • $\begingroup$ I think, easiest way to do this - scale parent down to 0 in one frame. $\endgroup$
    – Crantisz
    Mar 20, 2018 at 7:49
  • $\begingroup$ As a comment, as I've no idea how it was done. I've seen something like that done through drivers. Alternatively, have one .blend for the object groups (each parent with its children as a group), and a second .blend for the animation, where you link to the groups in your first .blend (used as a library)? $\endgroup$
    – remco
    Mar 20, 2018 at 8:13
  • $\begingroup$ This is a render time consideration, is that correct? $\endgroup$ Mar 20, 2018 at 9:16

2 Answers 2

3
$\begingroup$

EDIT, much better way to do this using properties

https://blender.stackexchange.com/a/147144/15543

https://blender.stackexchange.com/a/197072/15543

Fudge the driver system 2.9x

I removed the previous answer re doing this in 2.8, don't really recommend this one..

Melodicpinpon asks

Would it work in 2.9 version? This question has been debated in many places and this method could be the solution...

enter image description here

Using a method somewhat similar to @AtomicBezierSlinger can add a driver to every object in the scene that has a parent.

However the use of use self makes this driver readily copy pastable into other objects, without the need to check or set the parent object.

Here is a test script to add the driver to all objects with a parent.

import bpy

from bpy.app import driver_namespace as dns

def test(self, dg):
    vl = dg.view_layer
    return not self.parent.original.visible_get(view_layer=vl)
 
dns["test"] = test
   
context = bpy.context
scene = context.scene
#parented objects
parented = [o for o in scene.objects if o.parent]

for o in parented:
    #o.animation_data_clear() # testing
    #continue
    o.animation_data_create()
    fcurve = o.driver_add("hide_viewport")
    driver = fcurve.driver
    driver.expression = "test(self, depsgraph)"
    driver.use_self = True
    # dummy var to make driver update.
    var = driver.variables.new()
    var.name = "dummy" # frame
    var.targets[0].id_type = 'SCENE'
    var.targets[0].id = scene
    var.targets[0].data_path = "frame_current"

Making a test method and adding to the driver namespace is unnecessary as it can be directly crunched into expression field as

not self.parent.original.visible_get(view_layer=depsgraph.view_layer)

use self is not default and will need to be set.


answer below is for versions prior 2.8 with the use self option available. Also not a recommended way to use driver system.


Fudge the driver system

Firstly we'll set up a custom driver that sets a property of all children recursively to the value of the parent.

import bpy

def traverse_tree(t):
    yield t
    for child in t.children:
        yield from traverse_tree(child)

def set_children(obj, prop):
    val = getattr(obj, prop, None)
    if val is not None:
        for c in traverse_tree(obj): 
            setattr(c, prop, val)       
    return val    

bpy.app.driver_namespace["setchildprops"] = set_children

Now we can add a driver to a custom property on the same object as the property we wish to set on all children.

setchildprops(self, "hide")

making sure to check the non default "use_self" property of the driver.

enter image description here

Now if you keyframe the "hide" property of the same object it will hide / show children accordingly. Note it will not update the UI automatically, until some property eg frame is updated.

$\endgroup$
1
  • $\begingroup$ Anyone tried this with 2.82 too? $\endgroup$
    – wassx
    May 5, 2020 at 6:29
1
$\begingroup$
  • Consider a driver which copies the Render Visibility value of the parent. This will be successful.

  • The objects will still be available for [3D View Window] viewing. Only you can determine if this arrangement suits you.

  • You might even copy the [3D View Window] visibility based on the Render Visibility of the parent or any other object.
  • Please click on the image below to see a larger image.

enter image description here


  • The purple color on the visibility settings indicates a script. The eye dropper was used for the target ... the parents render visibilty. Arrow indicates the driver.
  • Consider the copy and paste of drivers from the context menu.

  • The contents of the driver are shown in the graph drivers pane.

  • You might even consider layer visibility to avoid clutter.
  • If you have a simple still shot ... you can move objects off the viewable area. This idea is for simple circumstances only.
$\endgroup$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .