44
Help us understand the problem. What are the problem?

More than 5 years have passed since last update.

posted at

updated at

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

プログラムから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);
    }

}

spine_creater.mov.gif

uGUIとの連携

デフォルトでは使いにくい。SortingLayerを使う。
CanvasはWorld SpaceにしてSortingLayer指定で、
前面と背面で分けておくと作りやすい。
この例ではButtonを使用している。
スクリーンショット 2015-05-22 23.56.11.png

アニメーション終了イベントをフック

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;

スクリーンショット 2015-05-23 1.22.22.png

スクリーンショット 2015-05-23 1.22.34.png

zファイティング問題

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

スクリーンショット 2015-05-23 1.39.16.png

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");

spine側はこんな感じ。Skinに含めないように。
スクリーンショット 2015-05-22 19.37.33.png

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

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
44
Help us understand the problem. What are the problem?