-
Notifications
You must be signed in to change notification settings - Fork 137
SkeletonObject Guide
Skeletal animation in Torque2D is provided by an integration with Spine (Esoteric Software). The skeleton scene object — the SpineObject class — is a sprite-like object derived from SceneObject that plays Spine animations. It draws a skin (the surface that's visible) deformed by a hierarchy of bones (the skeleton), using the data from a SkeletonAsset (the SpineAsset class).
A note on naming: for historical reasons these wiki pages are titled "Skeleton", but the actual engine classes are
SpineObjectandSpineAsset. The frozenmasterspinebranch (see below) is itself a little inconsistent about this — some of its bundled example assets still use the olderSkeletonAssettag andsetAnimationNamecalls that don't match the current classes. When in doubt, the_ScriptBinding.hfiles are the source of truth.
Spine is a commercial product, and including the Spine runtime in your project requires a valid Spine license from Esoteric Software — even if a particular game never actually uses Spine. To keep the main Torque2D engine free of that obligation, all Spine code was removed from master/development and now lives only on a separate branch named masterspine. None of the classes described on this page exist in a normal checkout — you have to bring the Spine code in yourself.
You'll merge the Spine code from masterspine into an up-to-date copy of the engine. If you're comfortable enough with Spine to want it, this will be familiar territory, but here's the full path:
- Get a Spine license from Esoteric Software if you don't already have one.
- Fork Torque2D on GitHub (so you have your own copy to commit the merge into) and clone your fork — or just clone the engine directly if you only want a local build.
- Make sure your working branch is up to date with the latest
master(ordevelopment). -
Fetch the Spine branch:
git fetch origin masterspine -
Merge it into a new branch and resolve the conflicts:
Expect a fair number of conflicts —
git checkout -b spine git merge origin/masterspinemasterspinewas branched from a much older version of the engine and has diverged significantly. Keep your up-to-date engine and add the Spine pieces on top of it: theengine/source/spine/runtime,engine/source/2d/assets/SpineAsset.*,engine/source/2d/sceneobject/SpineObject.*andSpineCollisionProxy.*, plus their console registrations. -
Wire the new sources into the build.
masterspinepredates Torque2D's move to CMake, so you must add the Spine source files tocmake/EngineSources.cmakeyourself (see Building from Source) — they won't be compiled otherwise. -
Build, then try the
SpineToyexample module that comes across in the merge.
Because this is a manual merge of a stale branch, treat it as real engineering work, not a one-click feature.
The Spine runtime on masterspine is spine-c 3.8 (its files carry a "Last updated January 1, 2020" header). The current Spine release is 4.3. This matters because Spine data must be exported from an editor version that matches the runtime — a skeleton exported from a modern Spine editor (4.x) will not load in the 3.8 runtime bundled here. Your two realistic choices are:
- Author with the older Spine 3.8 editor and export 3.8-compatible data, or
-
Update the bundled runtime yourself. Be aware this is not a drop-in swap: the runtime API changed substantially across 4.0 / 4.1 / 4.2 (4.2 added physics), and as of 4.3 Esoteric Software rewrote spine-c as an auto-generated wrapper over
spine-cpp. The Torque2D project does not plan to keep the Spine runtime current — maintaining or upgrading it is up to you.
(On the masterspine branch.)
The SpineObject type exposes the following fields in addition to those it inherits from SceneObject:
-
Asset — the SkeletonAsset (
SpineAsset) to use. - setSpineAsset(assetId)
- getSpineAsset()
- Skin — the skin to display.
- setSkin(skinName)
- getSkinName()
-
Scale — scaling of the skeleton geometry, as
"scaleX scaleY". - setScale(scaleX, scaleY)
- getScale()
- TimeScale — animation speed multiplier (1.0 = normal speed).
- setTimeScale(float)
- getTimeScale()
- AnimationData — a string encoding of the currently running animations (see Animations below).
- FlipX / FlipY — flip the skeleton horizontally / vertically.
- setFlipX(bool) / setFlipY(bool) / getFlipX() / getFlipY()
-
ActiveEffect — the active vertex effect (e.g. jitter), or
None. - JitterX / JitterY — amounts for the jitter vertex effect.
Spine animations run on numbered tracks, so you can play several at once (for example, "walk" on track 0 while "wave" plays on track 1).
- setAnimation(name, [track], [loop], [mixDuration]) — play an animation on a track.
- queueAnimation(name, [track], [loop], [mixDuration], [delay]) — queue an animation to play after the current one on a track.
- setEmptyAnimation([track], [mixDuration]) / queueEmptyAnimation(...) — clear a track toward the setup pose.
- clearAnimations([track], ...) / clearAllAnimations(...) — stop animations on one track or all tracks.
- getAnimationName([track]) — the animation currently playing on a track.
- getIsLooping([track]) — whether the track's current animation loops.
- setMix(fromAnimation, toAnimation, mixDuration) — set the crossfade duration between two animations.
The
AnimationDatafield is a tilde-separated encoding of every running track (per entry: name; track; looping; mix duration). It mainly exists so animation state survives a TAML save/load — for normal use, callsetAnimation/queueAnimation.
- enableJitter(x, y) / disableJitter() — turn a jitter vertex effect on or off.
- setJitterX(x) / setJitterY(y) / getJitterX() / getJitterY() — tune the jitter amounts.
%goblin = new SpineObject();
%goblin.Asset = "SpineToy:Goblins"; // a SkeletonAsset (SpineAsset)
%goblin.Skin = "goblin";
%goblin.setAnimation("walk", 0, true); // loop "walk" on track 0
%scene.add(%goblin);
(Heads-up: the SpineToy bundled in masterspine predates the current class API and uses older calls such as setAnimationName — prefer the methods documented above, and check SpineObject_ScriptBinding.h if something doesn't match.)