Spine Skeletonの画像を切り替える方法(Unity)


はじめに

Spineでボーンは共通でスキンのみを変えたいときがあるので、その方法のメモです。
(SpineUnityRunTimeのバージョンは4.0です)

スキン画像でSpineアトラス用の画像プリセットを適用する

通常通りに画像を追加した場合、アセットをTextureとして取得できなくなっていたので解決方法を書きます。
(Unityは2Dプロジェクトで、何かしらの設定が間違っていたかもしれません)

Spineマニュアル通りに各種データを追加した場合の画像は正しい設定で追加されるようです。

こちらから設定をプリセットとして保存して、

追加した画像も同じボタンからプリセットを適用することができます。

設定を同じにすることで、問題なく画像を使用できました。

SkeletonAnimationの場合

こちらは2Dワールド空間でスケルトンを表示する場合に使用するコンポーネントです。
以下の拡張メソッドを定義し、

public static class SpineExtension {

    public static void SetAtlasTexture(this SkeletonAnimation skeletonAnimation, string materialName, Texture texture) {
        foreach (var atlas in skeletonAnimation.skeletonDataAsset.atlasAssets) {
            foreach (var mat in atlas.Materials) {
                if (mat.name == materialName) {
                    var newMat = new Material(mat) {
                        mainTexture = texture
                    };
                    skeletonAnimation.CustomMaterialOverride[mat] = newMat;
                }
            }
        }
    }

}

呼び出すときは

[SerializeField] SkeletonAnimation _skeletonAnimation;

var texture = Resources.Load<Texture>("chara2");
_skeletonAnimation.SetAtlasTexture("chara_Material", texture);

でスキンを変えることができました。

SkeletonGraphicの場合

こちらはUiCanvas上でスケルトンを表示したいときに使用するコンポーネントです。

アトラスが一つの場合

この場合はOverrideTextureプロパティで新しいテクスチャをセットすれば大丈夫かと思います。

skeletonGraphic.OverrideTexture = texture;

アトラスが複数ある場合

Multiple CanvasRenderersにチェックを入れる

拡張関数を実装

public static class SpineExtension {

    public static void SetAtlasTexture(this SkeletonGraphic skeletonGraphic, string materialName, Texture texture) {
        skeletonGraphic.allowMultipleCanvasRenderers = true;
        skeletonGraphic.OverrideTexture = texture;
        foreach (var atlas in skeletonGraphic.skeletonDataAsset.atlasAssets) {
            foreach (var mat in atlas.Materials) {
                if (mat.name == materialName) {
                    skeletonGraphic.CustomTextureOverride[mat.mainTexture] = texture;
                }
            }
        }
    }

}

呼び出し時

[SerializeField] SkeletonGraphic _skeletonGraphic;

var texture = Resources.Load<Texture>("chara2");
_skeletonGraphic.SetAtlasTexture("chara_Material", texture);