HeadlinesBriefing favicon HeadlinesBriefing.com

Руководство по анимации Bevy: игрок и граф

Hacker News •
×

Итак, вы только что скачали анимированный 3D-файл персонажа .glb с бесплатного сайта ассетов. У вас есть базовое приложение Bevy. Теперь вы хотите создать своего персонажа в приложении Bevy. Достаточно легко, вероятно, для этого есть функция. Вы ищете базовый пример Animated Mesh на сайте Bevy... и быстро становится очевидным, что все не так просто, как вы надеялись. Много настроек, типы, связанные с анимацией, точное назначение которых не очевидно... Возможно, вы сможете быстро адаптировать примеры под свои нужды, но действительно сформировать мысленную модель того, как анимация работает в Bevy, на основе примеров, потребует серьезных размышлений.

Этот пост — то, что я хотел бы иметь, когда пытался понять анимацию в Bevy пару недель назад. Я начинаю с построения, шаг за шагом, достаточной мысленной модели для работы с базовой анимацией в Bevy. Затем я провожу вас через официальный пример, объясняя, как он соотносится с этой мысленной моделью, а также немного держу вас за руку, когда вы сталкиваетесь с методами, с которыми, возможно, еще не сталкивались. Если вы знакомы с основами ECS Bevy, вы — целевая аудитория этого поста.

Первая интуиция: Давайте на секунду забудем о Bevy и ECS и подумаем (очень абстрактно) о том, что нужно, чтобы анимированная 3D-модель двигалась. Вам нужны два ингредиента: созданная 3D-модель (или какая-то ссылка на нее), анимация для воспроизведения (или какая-то ссылка на нее). Итак, сначала вы можете ожидать, что воспроизведение анимации будет выглядеть примерно так: my_model.play_animation(my_animation); Вот наша мысленная модель на данный момент: Теперь это на самом деле несколько близко к тому, как работает реальная функция Bevy, а именно метод play из типа AnimationPlayer... или, по крайней мере, было бы, если бы его self действительно ссылался на 3D-модель, а его аргумент animation действительно ссылался на анимацию. Сейчас, однако, неясно, что это так. Но давайте более подробно рассмотрим, как наши два ингредиента представлены в Bevy, и, возможно, мы сможем согласовать нашу интуицию с тем, как работает функция play.

AnimationPlayer: Способ управления анимациями 3D-модели. Скажем, вы создаете 3D-модель из файла .glb. В идеале вы хотели бы ссылаться на нее, используя ID созданной сущности, за исключением того, что 3D-модели обычно не создаются как одна сущность, а скорее как иерархия сущностей: Чтобы анимировать вашу модель, вам нужно ссылаться на нее другим способом. В Bevy есть механизм для этого — ссылаться на 3D-модель для анимации — в виде типа AnimationPlayer. AnimationPlayer — это компонент, который автоматически вставляется в сущность... где-то в иерархии сущностей, соответствующей анимируемой 3D-модели, когда эта модель создается. Как только вы получили AnimationPlayer, вы можете сказать ему воспроизвести/приостановить анимацию, получить доступ к текущей воспроизводимой... но это предполагает, что у вас вообще есть анимации! Давайте сосредоточимся на них сейчас.

AnimationGraph: Способ хранения и комбинирования анимаций. Способ представления анимаций в Bevy немного сложен, потому что обычно вы манипулируете не отдельными анимациями, а экземплярами структуры данных, способной хранить несколько анимаций одновременно и комбинировать их друг с другом. Эта структура — AnimationGraph. Я не буду вдаваться в детали использования AnimationGraphs здесь; как только вы освоитесь с простыми анимациями, вы можете узнать больше об общих графах анимации на примере AnimationGraph. Пока мы сосредоточимся на случаях, когда наш граф содержит только одну интересующую нас анимацию. В этих случаях данные, идентифицирующие вашу анимацию, будут: (Ссылка на) AnimationGraph, Идентификатор того, где ваша анимация на самом деле находится внутри графа — для этого и предназначен тип NodeIndex.

Собираем все вместе: Итак, предположим, у вас есть AnimationPlayer, а также AnimationGraph и NodeIndex. Вот как вы их связываете, чтобы воспроизвести анимацию: Вставьте ссылку на ....