SpineをStarling1.7で使う:ランタイムでの基本的なSkeleton操作


SkeletonAnimationをインスタンス化するところまで以前の投稿で解説したので、今回はプログラムからの簡単な操作を行ってみます。ActionScrip3での操作ですが、大枠は他の言語でも同じはずです。(こまかいメソッド名は異なる模様。)

![デモ](https://qiita-image-store.s3.amazonaws.com/0/8302/b078f952-3a6f-943a-924e-ad61babb0e73.png)
今回のサンプルデモが[ここ](http://harayoki.github.io/qiita_demo/SpineTest2/)にあります。ボタンを押すと様々な操作ができます。サンプルデモはロードするたびに違うキャラクターがでます。(たまにででてくるの女の子は前回と同じ[wwikii](http://qiita.com/wwikii)さん作成のやつです。) キャラクターをクリックすると、UIボタンを隠すことができます。

デモのソースファイルは[ここ](https://github.com/harayoki/SpineTest1/blob/ScriptDemo1/src/demos/ScriptDemo1.as)にあります。

#情報取得系
こまかい情報は、SkeletonAnimation生成時に引数に渡したSkeletonDataが持っています。SkeletonAnimationから参照をたどることも可能です。アニメ一覧はskeletonData.animationsから、スキン一覧はskeletonData.skinsから取得できます。
`skeletonData.animations:Vector.<spine.animation.Animation>`
`skeletonData.skins:Vector.<spine.Skin>`

```sample.as
var skeletonAnimation = new SkeletonAnimation(skeletonData, true);
var skeleton:Skeleton = skeletonAnimation.skeleton;
trace(skeletonAnimation.skeleton.data == skeletonData); // true
trace(skeletonData.animations[0].name); // animation
trace(skeletonData.skins[0].name); // default
trace(skeletonData.defaultSkin == skeletonData.skins[0]); // true
```

#アニメーションを再生する
```sample.as
var state:AnimationState = skeletonAnimation.state;
var loop:Boolean = true;//ループ再生か
var animName:String = "animation";
//アニメーション名でアニメーションを指定
state.setAnimationByName(0, animName, loop);

//もしくは直接animationインスタンスで指定
var animation:Animation = skeletonData.findAnimation("animation");
state.setAnimation(0, animation, loop);
```
アニメーションの指定は、skeletonData.animationsから取得できるAnimationのnameをAnimationStateに設定します。（ミキシングやイベント管理など、いろいろ奥深そうなので、詳細は別の投稿にまとめます。）
上記だけだと停止したままなので、skeletonAnimationをStarlingのアニメーション機構であるjugglerに突っ込んでやります。一時停止やStopのメソッドはなさそうなので、停止時はjugglerから引っこ抜いてやります。

```sample.as
//再生
Starling.juggler.add(skeletonAnimation);
//停止
Starling.juggler.remove(skeletonAnimation);
```

jugglerは無理して使わず、`advanceTime()`メソッドを直接呼んでやった方が管理が楽かもしれません。引数は経過秒数です。

```sample.as
var sec = 1/60; //経過秒数
skeletonAnimation.advanceTime(sec);
```
元のポーズに戻したい場合はもう一度setAnimationByNameしてやります。アニメーション変更後はポーズをリセットするsetToSetupPose命令を呼んでやらないと、各パーツの状態がおかしいままになるようです。

```sample.as
skeletonAnimation.state.setAnimationByName(0, "hogeAnim", true);
skeletonAnimation.skeleton.setToSetupPose();
```
アニメ変更時のsetToSetupPoseはあえて行っていないので、setToSetupPoseボタンを押して対応してください。

![f](https://qiita-image-store.s3.amazonaws.com/0/8302/e359f3e4-043a-910b-ccdb-8f68fc698b80.png)
_エフェクトがでたまま固まって変になっているがsetToSetupPoseボタンを押すと直る_

#スキンを変更する

skeleton.skinを変更してやります。変更後にsetToSetupPoseを呼ばないと、変更が見た目に反映されないようです。

```sample.as
var skin:Skin = skeletonAnimation.skeleton.data.findSkin("skinName"); //名前からskin取得
skeletonAnimation.skeleton.skin = skin;
skeletonAnimation.skeleton.setToSetupPose(); // これを呼ばないと変わらない
```

![f](https://qiita-image-store.s3.amazonaws.com/0/8302/675867ee-ae0a-846e-5db0-ddac01888749.png)
なお、デモページでスキンデータが存在するのはゴブリンのデータだけで、読み込んだ直後は武器しか表示されないdefaultスキン状態になります。スキン変更時のsetToSetupPoseはあえて行っていないので、２つのボタンを押して対応してください。

![f](https://qiita-image-store.s3.amazonaws.com/0/8302/45366c61-b22c-2415-6ab9-1fdbe058800e.png)
_デフォルトスキン_

#移動・回転・拡大・Skew・反転

skeletonAnimationはDisplayObjectなので（SkeletonSpriteを継承しているがSpriteではない)、一通りの見た目の変更が効きます。またskeletonAnimation.skeleton側にもx,yのプロパティがあり、skeletonAnimationを移動できますが、通常は使わなくていいでしょう。(skeleton.xやskeleton.yを変えてもskeletonAnimationのx,yは変わらない)。反転に関してはskeleton.flipX、skeleton.flipYというBoolean値があります。skeletonAnimationのscaleを変更しないで反転できるので便利かもしれません。flip設定はアニメーションが再生されないと適用されないようです。

```sample.as
skeletonAnimation.x = 100;
skeletonAnimation.rotation = Math.PI/8;
skeletonAnimation.scaleX = 1.1;
skeletonAnimation.skewX = 0.2;
// 反転はscaleでもいいがflipX、flipYというプロパティもある
skeletonAnimation.skeleton.flipX = true;
skeletonAnimation.skeleton.y = 100; // yもある
```

![f](https://qiita-image-store.s3.amazonaws.com/0/8302/1561a209-7449-1ff0-86dc-e7026d297cad.png)
_メッシュアニメでもskewしてくれる_

#カラー・アルファの変更
skeleton.r、skeleton.g、skeleton.b、skeleton.aというパラメータがあり、こちらで色の変更が効きます。skeletonAnimation.colorプロパティはありません。それぞれデフォルト1.0ですが、Starlingのcolorプロパティと違い1.0以上の値も受け付け、輝くような表現が可能なので、便利ぽいです。alphaに関しては上記skeleton.aでもskeletonAnimation.alphaでも変更が効きます。

![](https://qiita-image-store.s3.amazonaws.com/0/8302/98b89623-8328-2d71-d02b-6b52a8c3e702.png)
_輝くBOY_

```sample.as
skeletonAnimation.skeleton.r = 2.0;
skeletonAnimation.skeleton.g = 0.5;
skeletonAnimation.alpha = 0.5;
```

![](https://qiita-image-store.s3.amazonaws.com/0/8302/76528d28-fcd8-ac35-f7f8-b0eacbc566f5.png)
半透明になった際、パーツの重なりが見えてしまうようで、そこは残念。

#基本操作対象まとめ

* StarlingのSpriteとしての操作 => SkeletonAnimationにアクセス
* スキンやアニメーションの変更、Bone(やSlotの操作) => Skeletonにアクセス
* アニメーション再生操作  => AnimationStateにアクセス
* その他基本情報にアクセス => SkeletonDataにアクセス

といった感じです。回りくどい感が若干ありますが、様々なランタイムを提供するためにこの形式の方が都合が良いのでしょう。

#次回以降
突っ込んだAnimation操作、Bone操作、Slot操作、当たり判定などを解説する予定です。Stay tuned.