technostallion

Unity、プログラム、グラフィック関係の技術ネタを書き殴ります

【Unity】【Spine】UnityランタイムのMecanim対応に伴う変更点

先日、SpineのUnityランタイムがMecanimに対応した。

Commits · EsotericSoftware/spine-runtimes · GitHub

この変更に伴い、一部ランタイムに互換性のない修正点が発生している。

GameObjectに紐付けたSpineコンポーネントを操作するユーティリティクラス、SkeletonUtilityのメンバにはSkeletonAnimationのインスタンス参照があり、従来はこれにドットシンタックスでアクセスして直接アニメーションを設定できた。

public class TestCharacter : MonoBehaviour
{
    // インスペクタからアタッチ
    public SkeletonUtility skeletonUtility;
    
    void Start ()
    {
        // アニメーション"foo"をワンタイム再生
        skeletonUtility.skeletonAnimation.state.SetAnimation( 0, "foo", false);
    }
}

こんな感じ。

今回のMecnaim対応でSkeletonAnimationはISkeletonAnimationインタフェースを実装した派生クラスに変更され、同じくISkeletonAnimationを実装したSkeletonAnimatorクラスがMecanim用のアニメーションコントローラーとして切り分けられた形だ。
ISkeletonAnimationインタフェースは以下のようになっていて、当然ながらstateへの参照はなく、上記のソースはコンパイルエラーになる。

public interface ISkeletonAnimation {
    event UpdateBonesDelegate UpdateLocal;
    event UpdateBonesDelegate UpdateWorld;
    event UpdateBonesDelegate UpdateComplete;

    void LateUpdate ();
}

解決策その1

ゲームオブジェクトからGetComponentのジェネリックで取得する。

// インスペクタからアタッチ
public SkeletonUtility skeletonUtility;

// 従来のアニメーションコントローラを取得
SkeletonAnimation skeletonAnimationInstance = skeletonUtility.gameObject.GetComponent<SkeletonAnimation>();

// Mecanim用アニメーションコントローラを取得
SkeletonAnimator skeletonAnimatorInstance = skeletonUtility.gameObject.GetComponent<SkeletonAnimator>();

シンプル。
既存箇所の修正がやや面倒。

解決策その2

プロパティで吸収する方法。
skeletonAnimationインタフェースのメンバをリネームする。

SkeletonUtility.cs
83行目あたり

[HideInInspector]
public ISkeletonAnimation skeletonAnimationBase;

そして以下のプロパティを追加する。

public SkeletonAnimation skeletonAnimation
{
    get
    {
        return skeletonAnimationBase as SkeletonAnimation;
    }
}

public SkeletonAnimator skeletonAnimator
{
    get
    {
        return skeletonAnimationBase as SkeletonAnimator;
    }
}

skeletonAnimationBaseをプロパティで包んでそれぞれキャストしてやる。
既存コードがそのまま動くのが利点。