|
@@ -1,243 +0,0 @@
|
|
|
----
|
|
|
-title: Скелетная Spine-анимация
|
|
|
-brief: Данное руководство объясняет как перенести скелетную Spine-анимацию из _Spine_ или _Dragon Bone_ в Defold.
|
|
|
----
|
|
|
-
|
|
|
-# Скелетная Spine-анимация
|
|
|
-
|
|
|
-_Spine_ --- это сторонний пакет анимации от компании Esoteric Software. Spine-анимация предоставляет поддержку двумерной скелетной анимации (см. [Скелетная анимация](https://ru.wikipedia.org/wiki/Скелетная_анимация)). Данная техника близка к перекладной анимации, при этом она в корне отличается от [мультикадровой](/manuals/flipbook-animation). В перекладной анимации отдельные части анимируемого объекта (то есть части тела, глаза, рот и т.д.) движутся независимо между кадрами. Spine-анимация позволяет выстраивать невидимые, виртуальные скелеты, состоящие из иерархии взаимосвязанных _костей_. Такой скелет, или по-другому _риг_, далее анимируется и отдельные изображения прикрепляются к его костям. Defold поддерживает анимацию созданную либо экспортированную в [Spine JSON-формате](http://esotericsoftware.com/spine-json-format). Скелетная анимация получается очень плавной поскольку движок интерполирует положение каждой кости для каждого кадра. На практике это весьма удобно для анимирования персонажей и животных, но также отлично работает и для других типов объектов, например, веревок, машин или растительности.
|
|
|
-
|
|
|
- {.inline}
|
|
|
- {.inline}
|
|
|
-
|
|
|
-Defold реализует во время выполнения игры вычисление и анимацию выраженную в [Spine JSON-формате](http://esotericsoftware.com/spine-json-format).
|
|
|
-
|
|
|
-Defold поддерживает большинство возможностей Spine-анимации, включая инверсную кинематику (IK).
|
|
|
-
|
|
|
-::: important
|
|
|
-На данный момент, Defold не поддерживает ключи анимации, которые переворачивают кости относительно осей X или Y. Defold поддерживает Mesh-анимацию, но только с костями, имеется в виду, что нельзя анимировать отдельные вершины. Если нужно анимировать отдельные вершины, можно сделать это посредством кости, которая на 100% привязана к данной вершине, анимируя эту кость.
|
|
|
-:::
|
|
|
-
|
|
|
-::: important
|
|
|
-Среда выполнения Spine реализованная в Defold поддерживает все возможности Spine версий 2.x. Среда выполнения предоставляет лишь ограниченную поддержку возможностей из Spine 3.x. Старайтесь задействовать только возможности из Spine 2.x, чтобы быть уверенными в совместимости со средой выполнения в Defold!
|
|
|
-:::
|
|
|
-
|
|
|
-## Концепции
|
|
|
-
|
|
|
-*Spine JSON файл данных*
|
|
|
-: Данный файл содержит скелет, все имена слотов изображений, скины и всю актуальную информацию об анимации. В этот файл не встраиваются никакие изображения. Создается такой файл подходящим приложением для анимации.
|
|
|
-
|
|
|
-*Spine-сцена*
|
|
|
-: Ресурс Defold, связывающий вместе Spine JSON файл данных и файл атласа с изображениями, которые используются под заполнение графикой слотов костей.
|
|
|
-
|
|
|
-*Spine-модель*
|
|
|
-: Компонент _Spine Model_ вставляется в игровой объект, чтобы вывести графику и анимацию на экран. Компонент содержит скелетную иерархию игрового объекта, информацию о том, которую из анимаций воспроизводить, какой применять скин, а также он задает материал, который будет задействован для рендеринга модели. За подробностями обращайтесь к [руководству по Spine Model](/manuals/spinemodel).
|
|
|
-
|
|
|
-*Spine-Нода*
|
|
|
-: В случае использования Spine-анимации в GUI-сцене, используйте Spine GUI-ноды вместо компонентов Spine Model. За подробностями обращайтесь к [руководству по GUI spine](/manuals/gui-spine).
|
|
|
-
|
|
|
-## Инструменты анимации
|
|
|
-
|
|
|
-Spine JSON файл данных поддерживаемый Defold может быть создан в ПО компании Esoteric Software _Spine_. Как вариант, _Dragon Bones_ умеет экспортировать в Spine JSON файл данных.
|
|
|
-
|
|
|
-_Spine_ доступен здесь: http://esotericsoftware.com
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-_Dragon Bones_ доступен здесь: http://dragonbones.com
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-::: important
|
|
|
-Обычно экспорт в Spine JSON файл данных в пакете _Dragon Bones_ работает без каких-либо проблем. Если Spine JSON файлов данных экспортированный из _Dragon Bones_ не рендерится должным образом в Defold, мы рекомендуем использовать официальное ПО [Spine Skeleton Viewer](http://esotericsoftware.com/spine-skeleton-viewer), чтобы сначала проверить, что данные парсятся корректно. Если возникает проблема с экспортированными данными на этом этапе, Spine Skeleton Viewer может подсветить проблемы в JSON файле данных, например, указав на недостающие или некорректные поля.
|
|
|
-:::
|
|
|
-
|
|
|
-
|
|
|
-## Импортирование Spine-персонажа и анимации
|
|
|
-
|
|
|
-Когда имеется модель и анимация, которые вы создали в Spine, процесс их импорта в Defold достаточно прост:
|
|
|
-
|
|
|
-- Экспортируйте Spine JSON версию данных анимации.
|
|
|
-- Расположите экспортированный JSON файл где-нибудь в иерархии вашего проекта.
|
|
|
-- Добавьте все изображения связанные с моделью где-нибудь в иерархии вашего проекта.
|
|
|
-- Создайте файл _Atlas_ и добавьте туда все изображения. (См. [руководство по 2D графике](/manuals/2dgraphics) чтобы лучше понять, как создаются атласы, а также см. предостережения ниже).
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-Если вы работаете в _Dragon Bones_, просто выберите *Spine* в качестве выходного типа данных. Также выберете *Images* как тип изображения. Таким образом, экспортируется *.json* файл и все необходимые изображения в одну папку. Добавьте далее содержимое этой папки в Defold как в шагах выше.
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-Когда есть данные анимации и файлы изображений импортированные и установленные в Defold, вам необходимо создать файл-ресурс _Spine scene_:
|
|
|
-
|
|
|
-- Создайте файл-ресурс _Spine scene_ (Выберите <kbd>New ▸ Spine Scene File</kbd> из главного меню)
|
|
|
-- Новый файл откроется в редакторе Spine-сцены.
|
|
|
-- Установите *Свойства*.
|
|
|
-
|
|
|
-{srcset="images/spine/[email protected] 2x"}
|
|
|
-
|
|
|
-Spine Json
|
|
|
-: Spine JSON файл, который будет использоваться как источник данных анимации и костей
|
|
|
-
|
|
|
-Atlas
|
|
|
-: Атлас, содержащий изображения, именованные в соответствии со Spine-файлом данных.
|
|
|
-
|
|
|
-## Создание компонентов Spine Model
|
|
|
-
|
|
|
-Когда есть все нужные импортированные данные и ресурс-файл _Spine Scene_ готов, можно создать компонент Spine Model. За подробностями обращайтесь к [руководству по Spine Model](/manuals/spinemodel).
|
|
|
-
|
|
|
-## Создание Spine GUI-нод
|
|
|
-
|
|
|
-Также можно использовать Spine-анимацию в GUI-сценах. За подробностями обращайтесь к [руководству по GUI spine](/manuals/gui-spine).
|
|
|
-
|
|
|
-## Воспроизведение анимации
|
|
|
-
|
|
|
-Для запуска анимации модели, просто вызовите функцию [`spine.play_anim()`](/ref/spine#spine.play_anim):
|
|
|
-
|
|
|
-```lua
|
|
|
-function init(self)
|
|
|
- -- Проиграть анимацию "walk" для компонента "spinemodel"
|
|
|
- -- и смешать ее относительно предыдущей анимации первые 0.1 секунд
|
|
|
- local anim_props = { blend_duration = 0.1 }
|
|
|
- spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props)
|
|
|
-end
|
|
|
-```
|
|
|
-
|
|
|
-{srcset="images/animation/[email protected] 2x"}
|
|
|
-
|
|
|
-Если анимация воспроизводится с каким-либо режимом вида `go.PLAYBACK_ONCE_*` и вы предоставили функцию обратного вызова в метод `spine.play_anim()`, функция сработает по окончании анимации. См. ниже информацию о функциях обратного вызова.
|
|
|
-
|
|
|
-### Анимация курсора
|
|
|
-
|
|
|
-В дополнении к использованию метода `spine.play_anim()` для более продвинутой анимации модели компоненты типа *Spine Model* предоставляют свойство "cursor", которым можно управлять с помощью вызова `go.animate()` (подробнее в [руководстве по анимации свойств](/manuals/property-animation)):
|
|
|
-
|
|
|
-```lua
|
|
|
--- Установить анимацию для Spine модели, но не проигрывать ее.
|
|
|
-spine.play_anim("#spinemodel", "run_right", go.PLAYBACK_NONE)
|
|
|
-
|
|
|
--- Выставить курсор в 0
|
|
|
-go.set("#spinemodel", "cursor", 0)
|
|
|
-
|
|
|
--- Сделать медленный твининг курсора между 0 и 1 в режиме Loop Ping Pong со смягчением InOutQuad
|
|
|
-go.animate("#spinemodel", "cursor", go.PLAYBACK_LOOP_PINGPONG, 1, go.EASING_INOUTQUAD, 6)
|
|
|
-```
|
|
|
-
|
|
|
-::: important
|
|
|
-При анимировании или установке позиции курсора, события временной шкалы могут срабатывать не так, как ожидается.
|
|
|
-:::
|
|
|
-
|
|
|
-### Иерархия костей
|
|
|
-
|
|
|
-Отдельные кости в Spine-скелете представлены в виде игровых объектов. В представлении *Outline* компонента Spine Model, видна вся иерархия. Вы можете видеть имя каждой кости и ее место в иерархии скелета.
|
|
|
-
|
|
|
-{srcset="images/animation/[email protected] 2x"}
|
|
|
-
|
|
|
-Зная имя кости, можно получить идентификатор экземпляра кости во время выполнения игры. Функция [`spine.get_go()`](/ref/spine#spine.get_go) возвращает идентификатор заданной кости и вы можете, например, сделать другие игровые объекты дочерними для данного анимируемого игрового объекта:
|
|
|
-
|
|
|
-```lua
|
|
|
--- Прикрепить игровой объект пистолета к руке героини
|
|
|
-local hand = spine.get_go("heroine#spinemodel", "front_hand")
|
|
|
-msg.post("pistol", "set_parent", { parent_id = hand })
|
|
|
-```
|
|
|
-
|
|
|
-### События таймлайна
|
|
|
-
|
|
|
-Spine-анимация может активировать временные события, посылая сообщения в определенные моменты. Они весьма удобны для событиый, которые должны произойти синхронно с вашей анимацией, например, проигрывание звука шагов, испускание эффектов частиц, присоединение или отсоединение объектов от иерархии костей или что-либо еще, что вы хотели бы выполнить.
|
|
|
-
|
|
|
-События добавляются в программе Spine и визуализируются на таймлайне воспроизведения:
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-Каждое событие имеет ссылку с именем идентификатора (в примере выше --- "bump"") и каждый экземпляр события на таймлайне может содержать дополнительную информацию:
|
|
|
-
|
|
|
-Integer
|
|
|
-: Числовое значение, выраженное типом integer.
|
|
|
-
|
|
|
-Float
|
|
|
-: Числовое значение с плавающей точкой.
|
|
|
-
|
|
|
-String
|
|
|
-: Строковое значение.
|
|
|
-
|
|
|
-Когда анимация воспроизводится и наступают события, сообщение `spine_event` посылаются обратно в тот скрипт, что вызвал `spine.play`. Данные сообщения содержат пользовательские числа и строки, встроенные в это событие, а также несколько дополнительных полей, которые также могут быть полезны:
|
|
|
-
|
|
|
-`t`
|
|
|
-: Количество секунд, прошедших после первого кадра анимации.
|
|
|
-
|
|
|
-`animation_id`
|
|
|
-: Имя анимации в хэшированном виде.
|
|
|
-
|
|
|
-`string`
|
|
|
-: Переданное строковое значение, в хэшированном виде.
|
|
|
-
|
|
|
-`float`
|
|
|
-: Переданное числовое значение с плавающей точкой.
|
|
|
-
|
|
|
-`integer`
|
|
|
-: Предоставленное целочисленное значение.
|
|
|
-
|
|
|
-`event_id`
|
|
|
-: Идентификатор события, в хэшированном виде.
|
|
|
-
|
|
|
-`blend_weight`
|
|
|
-: Указывает, какой процент от анимации будет использован в бленде в текущий момент времени. 0 означает, что ничего из текущей анимации не является частью бленда, 1 означает, что бленд состоит из текущей анимации на 100%.
|
|
|
-
|
|
|
-```lua
|
|
|
--- Spine-анимация содержит события, которые используются для проигрывания звуков синхронно с анимацией.
|
|
|
--- Эти события прибывают сюда в виде сообщений
|
|
|
-function on_message(self, message_id, message, sender)
|
|
|
- if message_id == hash("spine_event") and message.event_id == hash("play_sound") then
|
|
|
- -- Проиграть звук анимации. Пользовательские данные события содержат компонент звука и уровень усиления
|
|
|
- local url = msg.url("sounds")
|
|
|
- url.fragment = message.string
|
|
|
- sound.play(url, { gain = message.float })
|
|
|
- end
|
|
|
-end
|
|
|
-```
|
|
|
-
|
|
|
-## Завершающие функции обратного вызова
|
|
|
-
|
|
|
-Функция Spine-анимации `spine.play_anim()` поддерживают опциональные функции обратного вызова в качестве последнего переданного аргумента. Такие переданные функции будут вызваны когда анимация проиграется до конца. Функции никогда не будут вызваны для зацикленных анимаций, а также для анимаций, которые были отменены вручную вызовом `spine.cancel()`. Функция обратного вызова может быть использована для активации других событий по завершению анимации или для склеивания нескольких анимаций в одну цепочку.
|
|
|
-
|
|
|
-```lua
|
|
|
-local function anim_done(self)
|
|
|
- -- анимация проиграна, сделаем что-нибудь полезное...
|
|
|
-end
|
|
|
-
|
|
|
-function init(self)
|
|
|
- -- Проиграть анимацию "walk" для компонента "spinemodel" и смешать ее относительно предыдущей
|
|
|
- -- анимация для первых 0.1 секунды, затем вызвать функцию обратного вызова
|
|
|
- local anim_props = { blend_duration = 0.1 }
|
|
|
- spine.play_anim("#spinemodel", "run", go.PLAYBACK_LOOP_FORWARD, anim_props, anim_done)
|
|
|
-end
|
|
|
-```
|
|
|
-
|
|
|
-## Режимы воспроизведения
|
|
|
-
|
|
|
-Анимация может быть воспроизведена либо однократно либо зациклено. Как именно это происходит, определяется режимом воспроизведения:
|
|
|
-
|
|
|
-* go.PLAYBACK_NONE
|
|
|
-* go.PLAYBACK_ONCE_FORWARD
|
|
|
-* go.PLAYBACK_ONCE_BACKWARD
|
|
|
-* go.PLAYBACK_ONCE_PINGPONG
|
|
|
-* go.PLAYBACK_LOOP_FORWARD
|
|
|
-* go.PLAYBACK_LOOP_BACKWARD
|
|
|
-* go.PLAYBACK_LOOP_PINGPONG
|
|
|
-
|
|
|
-Режим Ping Pong проигрывает анимацию сначала вперед, затем в обратном порядке.
|
|
|
-
|
|
|
-## Предостережения по поводу атласов
|
|
|
-
|
|
|
-Данные анимации ссылаются на изображения, задействованные для костей, по имени с убранным суффиксом расширения файла. Вы добавляете изображения в Spine проект в программе Spine и они выстраиваются в иерархию в блоке *Images*:
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-Данный пример показывает расположение файлов в плоской структуре. Однако, возможно организовать файлы в подпапки и ссылки на файлы отразят такую структуру. Например, на файл *head_parts/eyes.png* на диске будет иметься ссылка как *head_parts/eyes* при использовании этого изображение для слота. Также, это имя будет использовано и в экспортированном JSON файле, поэтому для создаваемого атласа изображений в Defold, все имена должны совмещаться с анимациями атласа.
|
|
|
-
|
|
|
-При выборе <kbd>Add Images</kbd> Defold автоматически создаст группы анимаций с тем же именем как и добавленные файлы, но с вырезанным суффиксом расширения файла. Поэтому, после добавленного файла *eyes.png* его анимационная группа может быть доступна по ссылке с именем "eyes". Это работает только для имен файлов, но не путей.
|
|
|
-
|
|
|
-Так что следует сделать, если анимация имеет ссылку "head_parts/eyes"? Легкий способ добиться совпадения --- это добавить анимационную группу (правый клик по корневой ноде в области Atlas *Outline* и далее следует выбрать *Add Animation Group*). Затем можно называть группу "head_parts/eyes" (это просто имя, а не путь, так что символы `/` вполне допустимы) и затем добавить файл "eyes.png" в эту группу.
|
|
|
-
|
|
|
-{srcset="images/spine/[email protected] 2x"}
|
|
|
-
|
|
|
-Приступая к анимации Spine-модели, обращайтесь к [руководству по анимации](/manuals/animation).
|