UnityでSpineを扱う際に覚えておきたいTIPS

# プログラムからSpineオブジェクトを生成する
必要なファイルは以下の３つだけだが、実機でエラーが出る場合は、
Spine/SkeletonのShaderも紐付けておくと良いかもしれない。

・画像ファイル
・atlasテキストファイル
・jsonテキストファイル

```cs: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);
	}

}

```

![spine_creater.mov.gif](https://qiita-image-store.s3.amazonaws.com/0/26453/59c067d7-cd02-7b4d-bb4e-4620fb352556.gif)


# uGUIとの連携
デフォルトでは使いにくい。SortingLayerを使う。
CanvasはWorld SpaceにしてSortingLayer指定で、
前面と背面で分けておくと作りやすい。
この例ではButtonを使用している。
![スクリーンショット 2015-05-22 23.56.11.png](https://qiita-image-store.s3.amazonaws.com/0/26453/045dd1cd-840c-e731-4f86-e44893dc8a53.png)

# アニメーション終了イベントをフック
loop = trueの時はcountが増え続けながら毎回来る。

```cs: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。

```cs: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;
```

![スクリーンショット 2015-05-23 1.22.22.png](https://qiita-image-store.s3.amazonaws.com/0/26453/f3a78354-d108-e426-a179-abe6e5ba07a9.png)

![スクリーンショット 2015-05-23 1.22.34.png](https://qiita-image-store.s3.amazonaws.com/0/26453/7bbeb3a1-fb47-23d6-7fc4-6b9c2c2b3426.png)


# zファイティング問題
全く同じローカルz値を使用しているパーツが重なるとノイズが出る事がある。これをzファイティングと言う。これはz-spacingで回避出来る。
debugモードからz-spacingの値をいじってもいいし、
プログラムから値を与えてもいい。

![スクリーンショット 2015-05-23 1.39.16.png](https://qiita-image-store.s3.amazonaws.com/0/26453/127a7b68-2240-ec1e-fa60-1a396acf7c98.png)


```cs:SpineZSpacing.cs
skeletonAnimation.zSpacing = -1;
```

# Skinの動的変更
変更したらSetSlotsToSetupPose()を呼ぶこと。
呼ばないと反映されない。

```cs:SpineChangeSkin.cs
skeletonAnimation.skeleton.SetSkin(girlSkin ? "goblin" : "goblingirl");
skeletonAnimation.skeleton.SetSlotsToSetupPose();
```

# Attachmentの動的変更
SpineにはAttachmentというSkinの影響を受けない、
付加パーツのような仕組みがある。
これを切り替えるには、以下のコード。

```cs:SpineChangeAttachment.cs

skeletonAnimation.skeleton.SetAttachment("right hand item", null);
               skeletonAnimation.skeleton.SetAttachment("left hand item", "spear");
```

spine側はこんな感じ。Skinに含めないように。
![スクリーンショット 2015-05-22 19.37.33.png](https://qiita-image-store.s3.amazonaws.com/0/26453/d2d15ee3-95a5-e279-c7dc-93475aa9e75f.png)

他にも思いついたら追記。