Nobollelのエンジニアが、UnityやCocos2d-xの旬な情報・技術を紹介します。

Spine is a 2d based animation software, what makes it stand out is its ability to use bones and meshes, just like any 3d animation tool, to effortlessly create awesome 2d animation for your games. Another great feature is being able to use "skins" and "attachment", allowing you to reuse the same skeleton and animations for while switching out things like clothing and weapons for your character.

Importing and rigging

Before starting to animate, we need to import some images. All we have to do is finding the Images tab in the hierarchy and press the Browse button at the bottom, then select the folder with the images we want to import. We can now use the images by simply dragging them onto our stage, and arranging them how we want our model to look.

If you already have your model assembled in Photoshop or Gimp, you can use the export script to generate a JSON file that can be imported directly into Spine.

To create bones for your character, press the "Create new bones" at the bottom left of the screen, hold ctrl and click on the image you want to attach the bone to, then click and drag from where you want the actual bone. Remember to always select the bone you want as parent before creating new bones.

Animations

To create a new animation, find the Animations tab in the hierarchy and then press the "New Animation" button at the bottom of the screen. Once you have given your new Animation a name, press SETUP at the top left to go into animation mode.

The basics of the Dropsheet is to create one or more keyframe at different positions in the timeline, and Spine will tween between the two, making a smooth transition. To create a keyframe, press anywhere in the timeline where you want the new frame to be, then either move or rotate the body part you want to animate, or manually put in the values in the transform window above the Dropsheet.

You can also put "Events" in the timeline that can be used for things like footstep effects or to let your game know the exact timing to spawn the bullet in your shooting animation. Creating an event is just like creating animations, find the Event tab and press New Event. To use the event in your animation, go to the frame you want the event to occur, and press the small key next to the event you want to use.

Runtimes and scripting

To get our animations working in our game we need one the Spine runtime. Today i will be using the Cocos2d-x runtime, but spine is supported by a wide range of popular engines and languages, you can find a full list here.
http://esotericsoftware.com/spine-runtimes

Getting the character to show up in Cocos2d-x is super easy, if you have Cocos2d-x installed, you should already have the runtime too, but we need to add the header file to our class. I will also use the Spine namespace for convenience.

HelloWorld.h

#include <spine/spine-cocos2dx.h>
using namespace spine;

And with that we can add our character to our game!

HelloWorld.ccp

// creates a node holding our character
auto skeletonNode = SkeletonAnimation::createWithFile("res/koko.json", "res/koko00.atlas", 1.0f);
// the position we want our character to appear
skeletonNode->setPosition(Vec2(600, 10));
// (optional) called once a new animation starts
skeletonNode->setStartListener([skeletonNode] (int trackIndex) {
spTrackEntry* entry = spAnimationState_getCurrent(skeletonNode->getState(), trackIndex);
CCLOG("start: %s", entry->animation->name);
});
// (optional) called every time an animation is completed
skeletonNode->setCompleteListener([skeletonNode] (int trackIndex, int loopCount) {
CCLOG("loop count: %d", loopCount);
});
// (optional) this is called each time the animation runs into the events we added in spine
skeletonNode->setEventListener([skeletonNode] (int trackIndex, spEvent* event) {
CCLOG("event: %s", event->data->name);
});
// the most basic way to play an animation is to use setAnimation(
// int trackIndex, const std::string &animationName, bool loop)
skeletonNode->setAnimation(0, "walk", true);
// finally we can add the node to the stage
addChild(skeletonNode);