Самый простой способ заставить нужный объект появляться и исчезать – назначить ему ключи анимации. Для этого нужно навести курсор на значок глаза (видимость во вьюпорте) или фотоаппарата (видимость при рендере) в окне “Outliner”, нажать клавишу “i” и далее в Graph Editor управлять созданным ключом так же, как с обычными ключами анимации.
Но такой способ доступен не всегда. Например, для коллекций нельзя назначить ключи анимации видимости, Blender выдаст ошибки вида:
“hide_viewport” property cannot be animated
или
“hide_render” property cannot be animated
Однако с помощью Blender Python API видимостью таких объектов можно управлять.
Для примера создадим простейшую сцену с тремя объектами, каждый из которых находится в своей коллекции. На практике в одной коллекции может находиться много мешей, что позволяет удобно управлять видимостью всеми вложенными мешами через коллекцию.
Откроем текстовый редактор и создадим скрипт, управляющий видимостью трех коллекций cube, monkey и sphere.
Для начала для всех трех коллекций определим список кадров, на которых они будут скрываться или показываться.
1 2 3 4 5 |
import bpy bpy.data.collections['cube']['toggle_visibility_frame'] = [2, 22, 42, 62, 82] bpy.data.collections['monkey']['toggle_visibility_frame'] = [10, 70] bpy.data.collections['sphere']['toggle_visibility_frame'] = [25, 45, 66, 75] |
Мы добавили каждой коллекции новый атрибут “toggle_visibility_frame” и присвоили ему список с номерами кадров. Через этот список можно удобно назначать кадры для изменения видимости нужной коллекции.
Соберем коллекции, которым мы присвоили атрибут изменения видимости, в один список для удобного обращения.
1 |
collections_list = [collection for collection in bpy.data.collections if 'toggle_visibility_frame' in collection] |
Определим функцию, которая будет сверять значение текущего кадра со списком кадров из атрибута “toggle_visibility_frame” и если номер текущего кадра совпадает с номером, указанном в списке – менять видимость коллекции, скрывая или показывая ее.
1 2 3 4 5 |
def on_frame_change(scene): for collection in collections_list: if bpy.context.scene.frame_current in collection['toggle_visibility_frame']: collection.hide_render = not collection.hide_render collection.hide_viewport = not collection.hide_viewport |
Теперь нам нужно вызывать эту функцию при каждой смене кадра в таймлане. Привяжем вызов функции к событию смены кадра через обработчик события “frame_change_pre”, которое возникает каждый раз перед сменой очередного кадра в сцене.
1 2 3 4 |
from bpy.app import handlers if on_frame_change not in handlers.frame_change_pre: handlers.frame_change_pre.append(on_frame_change) |
Полный текст готового скрипта:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
import bpy from bpy.app import handlers bpy.data.collections['cube']['toggle_visibility_frame'] = [2, 22, 42, 62, 82] bpy.data.collections['monkey']['toggle_visibility_frame'] = [10, 70] bpy.data.collections['sphere']['toggle_visibility_frame'] = [25, 45, 66, 75] collections_list = [collection for collection in bpy.data.collections if 'toggle_visibility_frame' in collection] def on_frame_change(scene): for collection in collections_list: if bpy.context.scene.frame_current in collection['toggle_visibility_frame']: collection.hide_render = not collection.hide_render collection.hide_viewport = not collection.hide_viewport if on_frame_change not in handlers.frame_change_pre: handlers.frame_change_pre.append(on_frame_change) |
Выполним скрипт, нажав на кнопку “Run Script” и запустим проигрыш анимации.
В результате коллекции показываются и скрываются в соответствии с назначенными нами кадрами.