Read this manual in English

Скелетная Spine-анимация

Spine — это сторонний пакет анимации от компании Esoteric Software. Spine-анимация предоставляет поддержку двумерной скелетной анимации (см. Скелетная анимация). Данная техника близка к перекладной анимации, при этом она в корне отличается от мультикадровой. В перекладной анимации отдельные части анимируемого объекта (то есть части тела, глаза, рот и т.д.) движутся независимо между кадрами. Spine-анимация позволяет выстраивать невидимые, виртуальные скелеты, состоящие из иерархии взаимосвязанных костей. Такой скелет, или по-другому риг, далее анимируется и отдельные изображения прикрепляются к его костям. Defold поддерживает анимацию созданную либо экспортированную в Spine JSON-формате. Скелетная анимация получается очень плавной поскольку движок интерполирует положение каждой кости для каждого кадра. На практике это весьма удобно для анимирования персонажей и животных, но также отлично работает и для других типов объектов, например, веревок, машин или растительности.

Spine animation Run loop

Defold реализует во время выполнения игры вычисление и анимацию выраженную в Spine JSON-формате.

Defold поддерживает большинство возможностей Spine-анимации, включая инверсную кинематику (IK).

На данный момент, Defold не поддерживает ключи анимации, которые переворачивают кости относительно осей X или Y. Defold поддерживает Mesh-анимацию, но только с костями, имеется в виду, что нельзя анимировать отдельные вершины. Если нужно анимировать отдельные вершины, можно сделать это посредством кости, которая на 100% привязана к данной вершине, анимируя эту кость.

Среда выполнения Spine реализованная в Defold поддерживает все возможности Spine версий 2.x. Среда выполнения предоставляет лишь ограниченную поддержку возможностей из Spine 3.x. Старайтесь задействовать только возможности из Spine 2.x, чтобы быть уверенными в совместимости со средой выполнения в Defold!

Концепции

Spine JSON файл данных
Данный файл содержит скелет, все имена слотов изображений, скины и всю актуальную информацию об анимации. В этот файл не встраиваются никакие изображения. Создается такой файл подходящим приложением для анимации.
Spine-сцена
Ресурс Defold, связывающий вместе Spine JSON файл данных и файл атласа с изображениями, которые используются под заполнение графикой слотов костей.
Spine-модель
Компонент Spine Model вставляется в игровой объект, чтобы вывести графику и анимацию на экран. Компонент содержит скелетную иерархию игрового объекта, информацию о том, которую из анимаций воспроизводить, какой применять скин, а также он задает материал, который будет задействован для рендеринга модели. За подробностями обращайтесь к руководству по Spine Model.
Spine-Нода
В случае использования Spine-анимации в GUI-сцене, используйте Spine GUI-ноды вместо компонентов Spine Model. За подробностями обращайтесь к руководству по GUI spine.

Инструменты анимации

Spine JSON файл данных поддерживаемый Defold может быть создан в ПО компании Esoteric Software Spine. Как вариант, Dragon Bones умеет экспортировать в Spine JSON файл данных.

Spine доступен здесь: http://esotericsoftware.com

Spine

Dragon Bones доступен здесь: http://dragonbones.com

Dragon Bones

Обычно экспорт в Spine JSON файл данных в пакете Dragon Bones работает без каких-либо проблем. Если Spine JSON файлов данных экспортированный из Dragon Bones не рендерится должным образом в Defold, мы рекомендуем использовать официальное ПО Spine Skeleton Viewer, чтобы сначала проверить, что данные парсятся корректно. Если возникает проблема с экспортированными данными на этом этапе, Spine Skeleton Viewer может подсветить проблемы в JSON файле данных, например, указав на недостающие или некорректные поля.

Импортирование Spine-персонажа и анимации

Когда имеется модель и анимация, которые вы создали в Spine, процесс их импорта в Defold достаточно прост:

  • Экспортируйте Spine JSON версию данных анимации.
  • Расположите экспортированный JSON файл где-нибудь в иерархии вашего проекта.
  • Добавьте все изображения связанные с моделью где-нибудь в иерархии вашего проекта.
  • Создайте файл Atlas и добавьте туда все изображения. (См. руководство по 2D графике чтобы лучше понять, как создаются атласы, а также см. предостережения ниже).

Export JSON from Spine

Если вы работаете в Dragon Bones, просто выберите Spine в качестве выходного типа данных. Также выберете Images как тип изображения. Таким образом, экспортируется .json файл и все необходимые изображения в одну папку. Добавьте далее содержимое этой папки в Defold как в шагах выше.

Export JSON from Dragon Bones

Когда есть данные анимации и файлы изображений импортированные и установленные в Defold, вам необходимо создать файл-ресурс Spine scene:

  • Создайте файл-ресурс Spine scene (Выберите New ▸ Spine Scene File из главного меню)
  • Новый файл откроется в редакторе Spine-сцены.
  • Установите Свойства.

Setup the Spine Scene

Spine Json
Spine JSON файл, который будет использоваться как источник данных анимации и костей
Atlas
Атлас, содержащий изображения, именованные в соответствии со Spine-файлом данных.

Создание компонентов Spine Model

Когда есть все нужные импортированные данные и ресурс-файл Spine Scene готов, можно создать компонент Spine Model. За подробностями обращайтесь к руководству по Spine Model.

Создание Spine GUI-нод

Также можно использовать Spine-анимацию в GUI-сценах. За подробностями обращайтесь к руководству по GUI spine.

Воспроизведение анимации

Для запуска анимации модели, просто вызовите функцию spine.play_anim():

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

Spine model in game

Если анимация воспроизводится с каким-либо режимом вида go.PLAYBACK_ONCE_* и вы предоставили функцию обратного вызова в метод spine.play_anim(), функция сработает по окончании анимации. См. ниже информацию о функциях обратного вызова.

Анимация курсора

В дополнении к использованию метода spine.play_anim() для более продвинутой анимации модели компоненты типа Spine Model предоставляют свойство “cursor”, которым можно управлять с помощью вызова go.animate() (подробнее в руководстве по анимации свойств):

-- Установить анимацию для 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)

При анимировании или установке позиции курсора, события временной шкалы могут срабатывать не так, как ожидается.

Иерархия костей

Отдельные кости в Spine-скелете представлены в виде игровых объектов. В представлении Outline компонента Spine Model, видна вся иерархия. Вы можете видеть имя каждой кости и ее место в иерархии скелета.

Spine model hierarchy

Зная имя кости, можно получить идентификатор экземпляра кости во время выполнения игры. Функция spine.get_go() возвращает идентификатор заданной кости и вы можете, например, сделать другие игровые объекты дочерними для данного анимируемого игрового объекта:

-- Прикрепить игровой объект пистолета к руке героини
local hand = spine.get_go("heroine#spinemodel", "front_hand")
msg.post("pistol", "set_parent", { parent_id = hand })

События таймлайна

Spine-анимация может активировать временные события, посылая сообщения в определенные моменты. Они весьма удобны для событиый, которые должны произойти синхронно с вашей анимацией, например, проигрывание звука шагов, испускание эффектов частиц, присоединение или отсоединение объектов от иерархии костей или что-либо еще, что вы хотели бы выполнить.

События добавляются в программе Spine и визуализируются на таймлайне воспроизведения:

Spine events

Каждое событие имеет ссылку с именем идентификатора (в примере выше — “bump””) и каждый экземпляр события на таймлайне может содержать дополнительную информацию:

Integer
Числовое значение, выраженное типом integer.
Float
Числовое значение с плавающей точкой.
String
Строковое значение.

Когда анимация воспроизводится и наступают события, сообщение spine_event посылаются обратно в тот скрипт, что вызвал spine.play. Данные сообщения содержат пользовательские числа и строки, встроенные в это событие, а также несколько дополнительных полей, которые также могут быть полезны:

t
Количество секунд, прошедших после первого кадра анимации.
animation_id
Имя анимации в хэшированном виде.
string
Переданное строковое значение, в хэшированном виде.
float
Переданное числовое значение с плавающей точкой.
integer
Предоставленное целочисленное значение.
event_id
Идентификатор события, в хэшированном виде.
blend_weight
Указывает, какой процент от анимации будет использован в бленде в текущий момент времени. 0 означает, что ничего из текущей анимации не является частью бленда, 1 означает, что бленд состоит из текущей анимации на 100%.
-- 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(). Функция обратного вызова может быть использована для активации других событий по завершению анимации или для склеивания нескольких анимаций в одну цепочку.

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:

Spine images hierarchy

Данный пример показывает расположение файлов в плоской структуре. Однако, возможно организовать файлы в подпапки и ссылки на файлы отразят такую структуру. Например, на файл head_parts/eyes.png на диске будет иметься ссылка как head_parts/eyes при использовании этого изображение для слота. Также, это имя будет использовано и в экспортированном JSON файле, поэтому для создаваемого атласа изображений в Defold, все имена должны совмещаться с анимациями атласа.

При выборе Add Images Defold автоматически создаст группы анимаций с тем же именем как и добавленные файлы, но с вырезанным суффиксом расширения файла. Поэтому, после добавленного файла eyes.png его анимационная группа может быть доступна по ссылке с именем “eyes”. Это работает только для имен файлов, но не путей.

Так что следует сделать, если анимация имеет ссылку “head_parts/eyes”? Легкий способ добиться совпадения — это добавить анимационную группу (правый клик по корневой ноде в области Atlas Outline и далее следует выбрать Add Animation Group). Затем можно называть группу “head_parts/eyes” (это просто имя, а не путь, так что символы / вполне допустимы) и затем добавить файл “eyes.png” в эту группу.

Atlas path names

Приступая к анимации Spine-модели, обращайтесь к руководству по анимации.