В Blender я использую шаблон модального оператора для перемещения объекта и записи его положения в качестве ключевого кадра.
Я делаю примерно так:
import bpy
from bpy.props import IntProperty, FloatProperty
class ModalOperator(bpy.types.Operator):
"""Move an object with the mouse, example"""
bl_idname = "object.modal_operator"
bl_label = "Simple Modal Operator"
first_mouse_x = IntProperty()
first_value = FloatProperty()
current_frame = 1
endframe = bpy.data.scenes["Scene"].frame_end
def modal(self, context, event):
if event.type == 'MOUSEMOVE':
if self.current_frame < self.endframe:
delta = self.first_mouse_x - event.mouse_x
context.object.location.x = self.first_value + delta * 0.01
context.scene.frame_set(self.current_frame)
bpy.ops.anim.keyframe_insert_menu(type = "Rotation")
bpy.ops.anim.keyframe_insert_menu(type = "Location")
self.current_frame+=1
elif event.type == 'LEFTMOUSE':
return {'FINISHED'}
elif event.type in {'RIGHTMOUSE', 'ESC'}:
context.object.location.x = self.first_value
return {'CANCELLED'}
return {'RUNNING_MODAL'}
Бывает, что до того, как будут вставлены все ключевые кадры, и только после этого можно, например, переместить куб с помощью мыши. Я хотел бы переместить куб и одновременно «записать» его движение. Есть ли решение для этого?






Простым решением было бы включить блендеры Автоматическое определение ключевых кадров.
Если вы по-прежнему хотите, чтобы ваш оператор работал, я полагаю, вам не нужно будет вызывать других операторов и работать с данными напрямую, особенно в модальном операторе.
context.object.keyframe_insert('location')
context.object.keyframe_insert('rotation_euler')
@PaoloGambardella Я не думаю, что у вас может быть два модальных оператора, работающих одновременно, и оба реагируют на ввод пользователя. С автоматической настройкой ключевых кадров вы можете запускать воспроизведение и редактировать данные во время прокрутки кадров, скрипт не требуется.
Я понимаю, о чем вы говорите, но если я играю (ALT + A) с включенным автокреймингом и после активации скрипта, это не сработает. И этого не произойдет, если я сначала запускаю сценарий, а затем играю.
@PaoloGambardella - это два разных решения, которые вы смешиваете вместе. Пожалуйста, не надо. Предположительно, автоматическое определение ключевых кадров делает то, что вы изначально планировали, здесь нет необходимости в дополнительном операторе. Если это не так - я вижу два решения: либо имитировать другие операторы внутри вашего (т.е. реагировать на стандартные горячие клавиши, выполнять аналогичные действия и т. д.), Либо устанавливать обратный вызов перерисовки и пытаться перехватить что-то здесь; оба потребуют довольно большого кода и предположительно будут мешать «обычному» рабочему процессу.
@keltar спасибо за ответы. Я не смешиваю два подхода, на самом деле я также пытался удалить вызовы keyframe_insert и т.д., но все равно ничего не могу записать. Теперь я просто перемещаю свой объект, и ничего не происходит, даже если активирована вставка автоключевых кадров. Вместо этого, если я перемещаю свой объект с помощью функции «Захват», он работает. Это похоже на то, что созданный мной модальный оператор блокирует другие функции.
@PaoloGambardella, да, именно так. Вы используете события пользовательского ввода в своей функции modal. Вы можете передать некоторые события, если они вас не интересуют, но хотите, чтобы другие операторы реагировали с помощью return {"PASS_THROUGH"}, но если вы пройдете, например, Ключ g - оператор захвата начнет свою модальную операцию, и вы больше не будете получать никаких событий, пока она не завершится.
это странно, правда? То есть: - Я начинаю с ALT + A. После того, как я нажимаю G, начинается запись. Все ок - начинаю с ALT + A. После запуска сценария, который перемещает объект, НИЧЕГО не записывается. Почему?
@PaoloGambardella Alt-A и G, S, R запишут, как вы вручную перемещаете объект. Если вы используете сценарий для его перемещения, пусть сценарий также создает ключевые кадры во время его перемещения, например этот ответ.
это тоже не работает. Если я делаю что-то подобное, на самом деле он просто записывает все ключевые кадры и только затем перемещает объект с помощью моего контроллера.
Хорошо, я решил это.
Я вызывал keyframe_insert не для того объекта (анима, а не самого куба)
Это правильный способ вставить его, например, когда объект является камерой:
camera = bpy.context.scene.camera
camera.keyframe_insert(data_path='location', index=0)
camera.keyframe_insert(data_path='location', index=1)
camera.keyframe_insert(data_path='location', index=2)
camera.keyframe_insert('rotation_quaternion')
таким образом ключевые кадры вставляются в игру.
Здравствуйте, большое спасибо за ваш ответ. Сейчас я использую блендер 2.79. Если я включу автоматическое определение ключевых кадров или предложенное вами решение, у меня возникнет точно такая же проблема. Фактически, автоподстановка ключевых кадров работает, если, например, я захватываю объект с помощью G. Ничего подобного, если я перемещаю его по сценарию, не знаю почему.