Модальный оператор Blender не может вставлять ключевой кадр и перемещать объект

В 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'}

Бывает, что до того, как будут вставлены все ключевые кадры, и только после этого можно, например, переместить куб с помощью мыши. Я хотел бы переместить куб и одновременно «записать» его движение. Есть ли решение для этого?

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
355
2

Ответы 2

Простым решением было бы включить блендеры Автоматическое определение ключевых кадров.

Если вы по-прежнему хотите, чтобы ваш оператор работал, я полагаю, вам не нужно будет вызывать других операторов и работать с данными напрямую, особенно в модальном операторе.

context.object.keyframe_insert('location')
context.object.keyframe_insert('rotation_euler')

Здравствуйте, большое спасибо за ваш ответ. Сейчас я использую блендер 2.79. Если я включу автоматическое определение ключевых кадров или предложенное вами решение, у меня возникнет точно такая же проблема. Фактически, автоподстановка ключевых кадров работает, если, например, я захватываю объект с помощью G. Ничего подобного, если я перемещаю его по сценарию, не знаю почему.

Paolo Gambardella 16.11.2018 14:47

@PaoloGambardella Я не думаю, что у вас может быть два модальных оператора, работающих одновременно, и оба реагируют на ввод пользователя. С автоматической настройкой ключевых кадров вы можете запускать воспроизведение и редактировать данные во время прокрутки кадров, скрипт не требуется.

keltar 16.11.2018 15:02

Я понимаю, о чем вы говорите, но если я играю (ALT + A) с включенным автокреймингом и после активации скрипта, это не сработает. И этого не произойдет, если я сначала запускаю сценарий, а затем играю.

Paolo Gambardella 16.11.2018 15:08

@PaoloGambardella - это два разных решения, которые вы смешиваете вместе. Пожалуйста, не надо. Предположительно, автоматическое определение ключевых кадров делает то, что вы изначально планировали, здесь нет необходимости в дополнительном операторе. Если это не так - я вижу два решения: либо имитировать другие операторы внутри вашего (т.е. реагировать на стандартные горячие клавиши, выполнять аналогичные действия и т. д.), Либо устанавливать обратный вызов перерисовки и пытаться перехватить что-то здесь; оба потребуют довольно большого кода и предположительно будут мешать «обычному» рабочему процессу.

keltar 16.11.2018 17:06

@keltar спасибо за ответы. Я не смешиваю два подхода, на самом деле я также пытался удалить вызовы keyframe_insert и т.д., но все равно ничего не могу записать. Теперь я просто перемещаю свой объект, и ничего не происходит, даже если активирована вставка автоключевых кадров. Вместо этого, если я перемещаю свой объект с помощью функции «Захват», он работает. Это похоже на то, что созданный мной модальный оператор блокирует другие функции.

Paolo Gambardella 16.11.2018 17:10

@PaoloGambardella, да, именно так. Вы используете события пользовательского ввода в своей функции modal. Вы можете передать некоторые события, если они вас не интересуют, но хотите, чтобы другие операторы реагировали с помощью return {"PASS_THROUGH"}, но если вы пройдете, например, Ключ g - оператор захвата начнет свою модальную операцию, и вы больше не будете получать никаких событий, пока она не завершится.

keltar 16.11.2018 17:28

это странно, правда? То есть: - Я начинаю с ALT + A. После того, как я нажимаю G, начинается запись. Все ок - начинаю с ALT + A. После запуска сценария, который перемещает объект, НИЧЕГО не записывается. Почему?

Paolo Gambardella 16.11.2018 17:32

@PaoloGambardella Alt-A и G, S, R запишут, как вы вручную перемещаете объект. Если вы используете сценарий для его перемещения, пусть сценарий также создает ключевые кадры во время его перемещения, например этот ответ.

sambler 17.11.2018 05:20

это тоже не работает. Если я делаю что-то подобное, на самом деле он просто записывает все ключевые кадры и только затем перемещает объект с помощью моего контроллера.

Paolo Gambardella 19.11.2018 08:06

Хорошо, я решил это.

Я вызывал 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')

таким образом ключевые кадры вставляются в игру.

Другие вопросы по теме