4
$\begingroup$

I would need to know how to keyframe multiple (like 300) objects' show/hide property?

$\endgroup$
2
$\begingroup$

A possible solution would be to add a custom property to the scene that reflects the desired visibility state of the objects, and some Python code to apply that desired state to the actual objects.

import bpy

def interesting(ob) -> bool:
    """Returns True for objects to show/hide, and False otherwise.

    Alter to suit your needs.
    """

    return ob.name.startswith('Plane')

def hide_or_show(self, context=None):
    hide = self.hide_manus_objects
    for ob in self.objects:
        if not interesting(ob):
            continue
        # Change to ob.hide to hide from viewport instead of from render.
        # Or use ob.hide = ob.hide_render = hide to change both.
        ob.hide_render = hide


# Some cleanup in case you're running this multiple times.
try:
    del bpy.types.Scene.hide_manus_objects
except AttributeError:
    pass

# Responds to manual changes to the property.
bpy.types.Scene.hide_manus_objects = bpy.props.BoolProperty(
    name='hide_manus_objects', update=hide_or_show)
# Handles frame changes and thus responds to animation data.
bpy.app.handlers.frame_change_post.append(hide_or_show)

# Write to the property once to make it show up in the properties panel.
bpy.context.scene.hide_manus_objects = bpy.context.scene.hide_manus_objects

This does require you to alter the interesting() function to return True for those objects that you want to manage with this. Given that you have 300-ish objects, I'm assuming that there is some naming scheme that'll make this possible.

To use the code, just paste it into a text block and press "Run Script". If you want to have it active every time you open the blend file (you probably do), make sure the name of the text block ends in .py and enable the "Register" checkbox before saving.

$\endgroup$
  • $\begingroup$ I am testing this Python script, and I think there is a missing information here on where and how to trigger this function? $\endgroup$ – Blender Sushi Guy Nov 16 '17 at 0:41
  • 1
    $\begingroup$ The script creates the property, you'll find it in the scene custom properties panel. $\endgroup$ – dr. Sybren Nov 16 '17 at 21:58
  • 1
    $\begingroup$ Well, the idea is that you alter the code that says "Alter to suit your needs". I also noticed that the custom property only shows up after a value has been written to it, so I added that in the script (the last line). $\endgroup$ – dr. Sybren Nov 26 '17 at 0:41
  • 1
    $\begingroup$ OOooohhh, now I got it! :D I was a bit too much of an artist for reading the actual comments in the code. All clear now! Wheeeeee! $\endgroup$ – Manu Järvinen Dec 7 '17 at 16:21
  • 1
    $\begingroup$ And PHEW! What a nice thing I had an unique name for the object that I had copied all over the scene 1827 times to be precise here :) And yes, I only need to unhide them for the viewport (by using the ob.hide :) for the playback to be smooth on other parts of the timeline. $\endgroup$ – Manu Järvinen Dec 7 '17 at 16:27
5
$\begingroup$

Create an Empty, keyframe its Visibility property, select all the objects you'd like to hide/show, select the newly created Empty, press CtrlL to open up Make Links menu and select Animation Data.

enter image description here

Credit for the idea goes to @p2or, see: How to copy animation attributes to multiple objects?

$\endgroup$
  • $\begingroup$ Nice alternative solution and a nice gif! Even though this don't really work if the child objects already have some animation in them $\endgroup$ – Manu Järvinen Nov 16 '17 at 17:04
  • $\begingroup$ This is a kind of thing Blender is good at, hacky way, but link happy. $\endgroup$ – Blender Sushi Guy Nov 18 '17 at 6:08
2
$\begingroup$

As an alternative solution:

  1. manually select all objects you want to show/hide;
  2. alt-click the eye-icon or the render-icon in the outliner to show/hide them (in resp. the viewport or the render);
  3. run this script in a text block:

    import bpy
    
    for ob in bpy.context.selected_objects:
        ob.keyframe_insert(data_path="hide_render")
        ob.keyframe_insert(data_path="hide")
    

This is more manual work (you have to click around a lot more), and it produces 300-ish fcurves that you'll have to manually manage (rather than my other answer, which results in one fcurve only). However, the code is simpler, so if that floats your boat, use this approach

$\endgroup$
  • $\begingroup$ Great! Nice touch with the alt-clicking the eye-icon, I always forget this feature exists! One way also is, if you've border-selected the objects in the outliner, to right-click one of them and 'Toggle Visible' $\endgroup$ – Manu Järvinen Nov 16 '17 at 17:06
  • $\begingroup$ Also worth noting, at first when you press 'Run Script' it seems like nothing happens, you need to move on the timeline before the keyframes are put. $\endgroup$ – Manu Järvinen Nov 16 '17 at 17:15
  • $\begingroup$ And now I realized, how can you run the script when the objects are hidden... this might not work after all $\endgroup$ – Manu Järvinen Nov 16 '17 at 17:52
  • $\begingroup$ well that's why I first opted for a script that "knows" which objects you're dealing with. Of course it can be altered to loop over all objects in a group, all children of a certain empty, etc. $\endgroup$ – dr. Sybren Nov 16 '17 at 18:01
0
$\begingroup$

If using Nodes Add-On, you can do it this way:

SVERCHOK: enter image description here

ANIMATION NODES:

enter image description here enter image description here

Although, keyframing "node" is not as clear cut (not visible on the graph editor). There is a way around it by using controller that drives the node.

I would use Dr.Sybren answer above for now...

$\endgroup$

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.