プログラムからSpineオブジェクトを生成する
必要なファイルは以下の3つだけだが、実機でエラーが出る場合は、
Spine/SkeletonのShaderも紐付けておくと良いかもしれない。
・画像ファイル
・atlasテキストファイル
・jsonテキストファイル
SpineCreater.cs
using UnityEngine;
using System.Collections;
using Spine;
public class SpineCreater : MonoBehaviour {
// 画像ファイル
public Texture2D texture;
// atlasテキストファイル
public TextAsset atlasText;
// jsonテキストファイル
public TextAsset jsonText;
public void CreateSpineObject(){
// 1.Spine/Skeletonのmaterialを生成
Material material = new Material(Shader.Find("Spine/Skeleton"));
material.mainTexture = texture;
// 2.AtlasAssetを生成して、1のmaterialを紐づける
AtlasAsset atlasAsset = AtlasAsset.CreateInstance<AtlasAsset> ();
atlasAsset.atlasFile = atlasText;
atlasAsset.materials = new Material[1];
atlasAsset.materials [0] = material;
// 3.SkeletonDataAssetを生成して、初期データを投入する
SkeletonDataAsset dataAsset = SkeletonDataAsset.CreateInstance<SkeletonDataAsset> ();
dataAsset.atlasAssets = new AtlasAsset[1];
dataAsset.atlasAssets [0] = atlasAsset;
dataAsset.skeletonJSON = jsonText;
dataAsset.fromAnimation = new string[0];
dataAsset.toAnimation = new string[0];
dataAsset.duration = new float[0];
dataAsset.defaultMix = 0.2f;
dataAsset.scale = 1.0f;
// 4.実際にUnityに配置するGameObjectを生成して、SkeletonAnimationをadd
GameObject obj = new GameObject ("SpineObject");
SkeletonAnimation skeletonAnimation = obj.AddComponent<SkeletonAnimation> ();
MeshRenderer meshRenderer = obj.GetComponent<MeshRenderer>();
// sortingLayerを指定
meshRenderer.sortingLayerName = "spine";
meshRenderer.sortingOrder = 0;
// 5.SkeletonAnimationにSkeletonDataAssetを紐付け、skinName、reset(),animationNameを設定する。
skeletonAnimation.skeletonDataAsset = dataAsset;
// Reset()前に呼び出す必要あり。後に呼ぶとskinデータが反映されない
skeletonAnimation.initialSkinName = "goblin";
// Reset()時にDataAssetからAnimationデータを読みだして格納している
skeletonAnimation.Reset ();
// ループの設定はAnimation指定前じゃないと反映されない
skeletonAnimation.loop = true;
skeletonAnimation.AnimationName = "walk";
obj.transform.SetParent(this.gameObject.transform);
}
}
uGUIとの連携
デフォルトでは使いにくい。SortingLayerを使う。
CanvasはWorld SpaceにしてSortingLayer指定で、
前面と背面で分けておくと作りやすい。
この例ではButtonを使用している。
アニメーション終了イベントをフック
loop = trueの時はcountが増え続けながら毎回来る。
SpineAnimHook.cs
SkeletonAnimation skeletonAnimation = obj.GetComponent<SkeletonAnimation>();
// アニメ終了イベントをセット
skeletonAnimation.state.Complete += OnCompleteSpineAnim;
// アニメ終了イベント
private void OnCompleteSpineAnim(Spine.AnimationState state , int trackIndex , int loopCount){
Debug.Log(string.Format("state : {0} , trackIndex : {1} , loopCount : {2}" , state , trackIndex , loopCount));
}
色変更、透過
SkeletonAnimation内のSkeletonの値を変更でOK。
SpineColor.cs
SkeletonAnimation skeletonAnimation = obj.GetComponent<SkeletonAnimation>();
skeletonAnimation.skeleton.r = 1.0f;
skeletonAnimation.skeleton.g = 1.0f;
skeletonAnimation.skeleton.b = 1.0f;
skeletonAnimation.skeleton.a = 1.0f;
zファイティング問題
全く同じローカルz値を使用しているパーツが重なるとノイズが出る事がある。これをzファイティングと言う。これはz-spacingで回避出来る。
debugモードからz-spacingの値をいじってもいいし、
プログラムから値を与えてもいい。
SpineZSpacing.cs
skeletonAnimation.zSpacing = -1;
Skinの動的変更
変更したらSetSlotsToSetupPose()を呼ぶこと。
呼ばないと反映されない。
SpineChangeSkin.cs
skeletonAnimation.skeleton.SetSkin(girlSkin ? "goblin" : "goblingirl");
skeletonAnimation.skeleton.SetSlotsToSetupPose();
Attachmentの動的変更
SpineにはAttachmentというSkinの影響を受けない、
付加パーツのような仕組みがある。
これを切り替えるには、以下のコード。
SpineChangeAttachment.cs
skeletonAnimation.skeleton.SetAttachment("right hand item", null);
skeletonAnimation.skeleton.SetAttachment("left hand item", "spear");
他にも思いついたら追記。