(:3[kanのメモ帳]

個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。

(:3[kanのメモ帳]


本ブログの運営者kan.kikuchiが個人で開発した新作VRソフトです!


UnityでのSpineアニメーションの再生&変更方法、終了の検知方法、再生開始位置をランダムにする方法、再生(開始or終了)時に位置がズレる場合の対処法【Unity】【Spine】


このエントリーをはてなブックマークに追加


この記事でのバージョン
Unity 2019.4.26f1
spine-unity 3.8


はじめに

今回はSpineで作ったアニメーションをUnityで再生する方法と終了の検知方法、

ついでに再生開始位置をランダムにする方法再生(開始or終了)時に位置がズレる場合の対処法です!

f:id:kan_kikuchi:20210611080955g:plain


なお、SpineをUnityで使えるようにする導入方法については以下の記事を参照の事。



ちなみに記事中では使っている画像やアニメーションは、

上記の記事でも紹介したサンプルを使用しています。


アニメーションの再生方法と終了の検知方法

まず、SkeletonAnimationのAnimation Nameで再生するアニメーションを指定する事が出来ます。

f:id:kan_kikuchi:20210610062043p:plain


また、何というアニメーションが設定されているかも確認する事が可能です。

f:id:kan_kikuchi:20210610062418p:plain


プログラムからアニメーションを再生する場合もこのSkeletonAnimationを使います。

具体的にはstateのSetAnimationにトラック番号(int)、アニメーション名(string)、

ループするか(bool)の引数を指定して再生します。

_skeletonAnimation.state.SetAnimation(trackIndex, animationName, isLoop);


例えばIdleというアニメーションをトラック0でループ再生したい場合は以下のような感じに。

_skeletonAnimation.state.SetAnimation(0, "Idle", true);
f:id:kan_kikuchi:20210611062651g:plain


トラック番号は基本的には0で大丈夫ですが、

複数のトラック番号を使う事で、異なるアニメーションを合成して再生する事も可能です。


なお、再生終了を検知して処理をしたい(コールバックを設定したい)場合は

SetAnimationの返り値でTrackEntry を取得し、そのTrackEntryのCompleteに処理を登録します。

(※ループ再生の場合は1ループ終わる度に処理が実行される)

//TrackEntryを取得し終了時のメソッドを登録
TrackEntry trackEntry = _skeletonAnimation.state.SetAnimation(trackIndex, animationName, isLoop);
trackEntry.Complete += OnCompleteAnimation;
//アニメーション終了
private void OnCompleteAnimation(TrackEntry trackEntry){
  Debug.Log($"アニメーション終了 : {trackEntry.Animation.Name}");
}
f:id:kan_kikuchi:20210611080955g:plain


また、TrackEntryのAnimationStartでアニメーションの開始時間、AnimationEndで終了時間が取得でき、

TrackTimeで現在の時間を指定出来るので、以下のように再生開始時間をランダムにする事も可能です。

//ループ再生開始と同時にTrackEntry取得
TrackEntry trackEntry = _skeletonAnimation.state.SetAnimation(trackIndex, animationName, isLoop);

//現在の再生時間を再生開始時間~再生終了時間の間でランダムに設定
trackEntry.TrackTime = UnityEngine.Random.Range(trackEntry.AnimationStart, trackEntry.AnimationEnd);

//設定した時間の状態に瞬時になるように更新
_skeletonAnimation.state.Update(trackIndex);
f:id:kan_kikuchi:20210611082132g:plain


ちなみに前のアニメが残っていると

再生終了時に動きがおかしくなる事があるので再生開始前にstate.ClearTrackを、

各パーツの位置を戻さないとズレる事があるので、

再生開始直後にskeleton.SetToSetupPoseを実行するのがオススメです。

//前のアニメを消去(残っていると再生終了後におかしくなる事がある)
_skeletonAnimation.state.ClearTrack(trackIndex);

//アニメ生成開始
_skeletonAnimation.state.SetAnimation(trackIndex, animationName, isLoop);
    
//SetToSetupPoseで各パーツの位置を戻す(ズレる事があるので)
_skeletonAnimation.skeleton.SetToSetupPose();