<div style="padding:15px 15px 2px 20px; border-radius:2px; margin-bottom:20px; border:1px solid #ddd">

<callout>
<p style="margin-bottom:0.75em"><b>ライセンスについて</b></p>!!
Spineランタイムをアプリケーションに組み込むにはSpineライセンスが[必要](/git/spine-runtimes/spine-unity#licensing)です。
</callout>

<div style="font-size: 1.6em; margin: 0 0 .5em;">spine-unityランタイム ドキュメント</div>!!
* [インストール](/spine-unity-installation)
* [サンプル](/spine-unity-examples)
* [アセット](/spine-unity-assets)
* [主要なコンポーネント](/spine-unity-main-components)
* [ユーティリティコンポーネント](/spine-unity-utility-components)
* [レンダリング](/spine-unity-rendering)
* [Timeline 拡張UPMパッケージ](/spine-unity-timeline)
* [オンデマンドローディング 拡張UPMパッケージ](/spine-unity-on-demand-loading)
* [FAQ](/spine-unity-faq)
</div>!!

> **重要な注意事項**: このページは**4.3およびそれ以降**のバージョンにおけるスケルトンコンポーネントについて説明しています。  
> **4.2およびそれ以前のバージョンについては、[こちらのページ](/spine-unity-main-components-4.2)を参照してください**。

# 主要なコンポーネント

spine-unityランタイムは、Spineからエクスポートされたスケルトンの表示、アニメーション、追従および修正を可能にするコンポーネントのセットを提供します。これらのコンポーネントは、[アセットセクション](/spine-unity-assets#SpineアセットのUnityへのインポート)で説明されているインポートされたスケルトンデータとテクスチャアトラスアセットを参照します。

> **注意:** **spine-unity 4.3**ランタイムでは、主要なアーキテクチャの変更が導入されました: 具体的には、コンポーネントの継承ではなく**二つの独立したコンポーネント**を使用することで、**アニメーションとレンダリングの分離**を行いました。これにより、従来は不可能であった、より柔軟な組み合わせが可能となりました。

## スケルトンをシーンに追加する
ご自身のUnityプロジェクトでSpineスケルトンを素早く表示するには ：

1. [アセットセクション](/spine-unity-assets#SpineアセットのUnityへのインポート)で説明されているスケルトンデータとテクスチャアトラスをインポートします。
2. **_SkeletonData**アセットをSceneビューまたはHierarchyパネルにドラッグし、`SkeletonAnimation` を選択します。  
すると、あらかじめ以下のSpineコンポーネントが設定された新しいGameObjectがインスタンス化されます:
`SkeletonRenderer` は描画とスケルトンの管理のためのコンポーネントです。`SkeletonAnimation` スケルトンはそれをアニメーションさせます。
![](/img/spine-runtimes-guide/spine-unity/drag-and-drop-instantiate.gif)

> **補足:**　STEP2の代わりに、同じGameObjectをいちから作ることもできます ：
1. `GameObject -> Create Empty` で空のGameObjectを新規作成します。
2. GameObjectを選択し、Inspectorで `Add Component` をクリックして、`SkeletonRenderer`を選択することで、`SkeletonRenderer`コンポーネントを追加します。これにより、追加の `MeshRenderer` と`MeshFilter` コンポーネントも自動的に追加されます。
3. [SkeletonRenderer](#SkeletonRendererコンポーネント)で**_SkeletonData**をドラッグして `Skeleton Data Asset` プロパティに割り当てます。
4. GameObjectに`SkeletonAnimation`コンポーネントを追加してます。GameObjectを選択し、Inspectorで再び `Add Component` をクリックして、`SkeletonAnimation` を選択してください。

> **注意:**　Sceneビューで、画像がアタッチされていないボーンだけのスケルトンが表示されてしまう場合、`Initial Skin` プロパティを `default` 以外のスキンに切り替えてください。

これで、コンポーネントのC# APIを使って、スケルトンをアニメーションさせたり、アニメーション中で発生するイベントへの反応などができるようになります。詳細は後述のコンポーネントのドキュメントを参照してください。

### レンダリングコンポーネントとアニメーションコンポーネント

UnityでSpineスケルトンを使用する際には、[ドラッグ＆ドロップ](#スケルトンをシーンに追加する)でスケルトンをインスタンス化し、`SkeletonAnimation` を選択することをお勧めします。これにより、アニメーション用コンポーネント「[SkeletonAnimation](#SkeletonAnimationコンポーネント)」と、レンダリング用コンポーネント「[SkeletonRenderer](#SkeletonRendererコンポーネント)」を備えたGameObjectが生成され、他の選択肢に比べて最も完全な機能セットを提供します。

ただし、`SkeletonRenderer` が使用できない状況もあります。例えば、UI Canvas内でのレンダリング時や、サードパーティ製アセットとの連携のためにMecanimを使用したアニメーションが必要な場合などです。レンダリング用とアニメーション用、それぞれ使用可能なコンポーネントは以下の通りです：

**レンダリングコンポーネント**
1. **[SkeletonRenderer](#SkeletonRendererコンポーネント)** - 標準の `MeshRenderer` を利用し、Unityのスプライトと同様に `SpriteMask` などのマスクと連動します。*UnityにおけるSpineスケルトンのレンダリングでは最も推奨される方法です。*
2. **[SkeletonGraphic (UI)](#SkeletonGraphicコンポーネント)** - Unityの `Canvas` と共にUI要素として使用します。UnityのビルトインUI要素と同様、`RectMask2D` などのUIマスクをレンダリングし、連動できます。

**アニメーションコンポーネント**
1. **[SkeletonAnimation](#SkeletonAnimationコンポーネント)** - Spineのカスタムアニメーションおよびイベントシステムを採用しており、最高レベルのカスタマイズ性を提供します。*UnityにおけるSpineスケルトンのアニメーション化では最も推奨される方法です。*
2. **[SkeletonMecanim](#SkeletonMecanimコンポーネント)** - UnityのMecanimアニメーションおよびイベントシステムを使用して、アニメーションの開始、ミックス、および遷移を行います。[SkeletonAnimation](#SkeletonAnimationコンポーネント)と比較して、アニメーションのミックスおよび遷移のオプションは少なくなっています。`SkeletonMecanim` を使用する場合、遷移がSpineエディター上でプレビューされた通りの見た目にならない場合があることに注意が必要です。

[ドラッグ＆ドロップ](#スケルトンをシーンに追加する)した時に表示されるメニュー内の4つのオプションは、既存の命名規則および自動アップグレード方式に従い、以下のコンポーネントの組み合わせを表しています：
1. **SkeletonAnimation**: [SkeletonAnimation](#SkeletonAnimationコンポーネント) + [SkeletonRenderer](#SkeletonRendererコンポーネント)。*UnityでSpineスケルトンを利用する場合において最も推奨される方法です*
2. **SkeletonGraphic (UI)**: [SkeletonAnimation](#SkeletonAnimationコンポーネント) + [SkeletonGraphic (UI)](#SkeletonGraphicコンポーネント).
3. **SkeletonMecanim**: [SkeletonMecanim](#SkeletonMecanimコンポーネント) + [SkeletonRenderer](#SkeletonRendererコンポーネント)。
4. **SkeletonGraphic (UI) Mecanim**: [SkeletonMecanim](#SkeletonMecanimコンポーネント) + [SkeletonGraphic (UI)](#SkeletonGraphicコンポーネント)。

### 高度な情報 - 実行中でのインスタンス化

> **注意:** 通常のワークフローでは、シーンにスケルトンを追加してプレハブに格納するか、インスタンスプールからプールされたオブジェクトを再利用してインスタンス化するのが望ましいです。その方がカスタマイズや調整が容易になります。

推奨されるワークフローではありませんが、spine-unity APIでは、`SkeletonDataAsset`、またはエクスポートされた3つのアセットから直接、実行中に`SkeletonAnimation` と `SkeletonGraphic` をインスタンス化することができます。エクスポートされたアセットから直接インスタンスを作成するのは、通常のUnityインポートパイプラインでは `SkeletonDataAsset` と `SpineAtlasAsset` を事前に自動作成できない場合にのみ行うことを推奨します。

```csharp
// SkeletonAnimation GameObject を SkeletonDataAsset からインスタンス化する
SkeletonComponents<SkeletonRenderer, SkeletonAnimation> instance
	= SkeletonAnimation.NewSkeletonAnimationGameObject(skeletonDataAsset);

// SkeletonGraphic GameObject を SkeletonDataAsset からインスタンス化する
SkeletonComponents<SkeletonGraphic, SkeletonAnimation> instance
	= SkeletonGraphic.NewSkeletonGraphicGameObject(skeletonDataAsset, transform, skeletonGraphicMaterial);

// 任意のレンダラーとアニメーションコンポーネントの組み合わせの汎用インスタンス化
// SkeletonRenderer.NewSpineGameObject<RendererType, AnimationType>();
var instance = SkeletonRenderer.NewSpineGameObject<SkeletonRenderer, SkeletonMecanim>(skeletonDataAsset);
// SkeletonGraphic.NewSkeletonGraphicGameObject<AnimationType>();
var graphicInstance = SkeletonGraphic.NewSkeletonGraphicGameObject<SkeletonMecanim>(skeletonDataAsset, parent, material);
```

```csharp
// エクスポートしたアセットを事前にインポートせずにインスタンス化する場合
// 1. AtlasAssetを作成して (atlas.textアセットとテクスチャ、マテリアル/シェーダーが必要です)、
// 2. SkeletonDataAssetを作成します (JSONまたはバイナリアセットファイル、およびAtlasAssetが必要です)
SpineAtlasAsset runtimeAtlasAsset
	= SpineAtlasAsset.CreateRuntimeInstance(atlasTxt, textures, materialPropertySource, true);
SkeletonDataAsset runtimeSkeletonDataAsset
	= SkeletonDataAsset.CreateRuntimeInstance(skeletonJson, runtimeAtlasAsset, true);
// 3. Create SkeletonAnimation (needs a valid SkeletonDataAsset)
SkeletonAnimation instance = SkeletonAnimation.NewSkeletonAnimationGameObject(runtimeSkeletonDataAsset);
```

サンプルシーン `Spine Examples/Other Examples/Instantiate from Script` や、そこで使用されているサンプルスクリプト `SpawnFromSkeletonDataExample.cs`、`RuntimeLoadFromExportsExample.cs`、`SpawnSkeletonGraphicExample.cs` でさらに詳しく確認できます。


## SkeletonRendererコンポーネント

`SkeletonRenderer` コンポーネントは、スケルトンのレンダリングおよび現在の状態の管理を担当します。これは2つあるスケルトンのレンダリング用コンポーネントのうちの1つであり、もう1つはCanvas UI要素向けの[SkeletonGraphic (UI)](#SkeletonGraphicコンポーネント) コンポーネントです。

![](/img/spine-runtimes-guide/spine-unity/skeleton-renderer-component-43.png)

レンダリングは、`MeshRenderer` コンポーネントにおいてプロシージャルメッシュを介して行われます。このコンポーネントは、[SkeletonDataAsset](/spine-unity-assets#Skeleton-Data-Asset)によって参照されるテクスチャアトラスアセットを使用し、スケルトンのアタッチメントを描画するために必要なテクスチャとマテリアルを検索します。

> **補足:** ほとんどの場合、アニメーションの制御や遷移処理を行うために、[SkeletonAnimation](#SkeletonAnimationコンポーネント)や[SkeletonMecanim](#SkeletonMecanimコンポーネント)といったアニメーションコンポーネントも併せて追加することになるでしょう。遷移なしで手動でアニメーションを適用する必要がある場合（例えばゲージUIのアニメーションなど）に限り、このコンポーネント単体で使用してください。
`SkeletonRenderer` コンポーネントを直接使用する方法については、サンプルシーン
`Spine Examples/Other Examples/SpineGauge` を参照してください。

### Skeleton Data設定
[SkeletonRenderer](#SkeletonRendererコンポーネント)コンポーネントは、スケルトンのボーン階層やスロットなどの情報を取得できるスケルトンデータアセットへの参照を必要とします。

スケルトンを[ドラッグ＆ドロップ](#スケルトンをシーンに追加する)でシーンに追加した場合、そのスケルトンデータアセットが自動的に割り当てられます。
既に設定されているGameObjectがあってそのスケルトンを別のアセットに変更したくなった場合は、Inspectorプロパティを使って手動で変更することができます。

スケルトンデータを設定・変更するには

1. [SkeletonRenderer](#SkeletonRendererコンポーネント) GameObjectを選択します。
2. Inspectorの `SkeletonData Asset` プロパティに **_SkeletonData** アセットを割り当てます。

### プロパティ

[SkeletonRenderer](#SkeletonRendererコンポーネント)のInspectorでは、以下のプロパティを設定できます：
* *Initial Skin* ：　 スタート時に割り当てられるスキンです。注：画像が一切表示されずスケルトンのボーンのみが表示される場合、default以外のスキンに切り替えて、作成したスキンを表示してください。
* *Initial Flip X、Initial Flip Y* ：　スタート時にスケルトンを水平方向および垂直方向に反転させる設定です。反転した方向の*ScaleX*および*ScaleY*は*-1*に設定されます。

<h3>高度なパラメーターの設定<span id="Setting-Advanced-Parameters"></span></h3>!!

[SkeletonRenderer](#SkeletonRendererコンポーネント)のInspectorの `Advanced` セクションを展開すると、高度な設定パラメーターが表示されます。

![](/img/spine-runtimes-guide/spine-unity/skeleton-renderer-component-43-advanced.png)

[SkeletonRenderer](#SkeletonRendererコンポーネント)のInspectorでは、以下の詳細なパラメーターを公開しています:

* *Update When Invisible* ：　MeshRendererが非表示になったときに使用されるアップデートモードを設定します。メッシュが再び表示されるようになると、アップデートモードは自動的に `UpdateMode.FullUpdate` にリセットされます。
* *Fix Draw Order* ：　この設定は3つ以上のサブメッシュが使用されている場合のみ適用されます（2つ以上のマテリアルが交互に並んでいる場合、例：「A B A」）。trueの場合、MaterialPropertyBlockが各マテリアルに割り当てられ、LWRPレンダラーなどによるサブメッシュの積極的なバッチ処理を防ぎ、誤った描画順序になるのを防ぎます（例：「A1 B A2」が「A1 A2 B」に変更される等）。すべてが正しく描画されている場合は、このパラメーターを無効にしておくことでパフォーマンスコストを節約することができます。
* *Immutable triangles* ：　この設定は、アタッチメントの表示状態を変更することが無いスケルトンのレンダリングを最適化するために有効にすることができます。trueの場合、三角形が更新されなくなります。スケルトンがアタッチメントの切り替えや非表示、または描画順序キーを使用しない場合、最適化のためにこれを有効にします。そうでない場合は、これをfalseに設定するとレンダリングでエラーが発生する可能性があります。
* *Clear State on Disable* ：　このコンポーネントまたはそのGameObjectが無効になったときに、レンダーとスケルトンの状態をクリアする設定です。これにより、再び有効になったときに以前の状態が保持されるのを防ぐことができます。スケルトンをプールする場合は、これをtrueに設定すると便利です。
* *Separator Slot Names* ：　レンダリングを分割する場所を決めるスロットを設定します。これは `SkeletonRenderSeparator` などのコンポーネントで使用され、スケルトンを異なるGameObject上に2つの別々のレンダラーでレンダリングすることができます。
* *Use Clipping*. When set to `false`, any [Spine clipping attachments](/spine-clipping) will be ignored.
* *Z-Spacing* ：　 この設定を変更すると、アタッチメントがスケルトンのレンダラーコンポーネントによって、x/y平面上で前後にレンダリングされるようになります。各アタッチメントが、z軸上のカスタマイズ可能なz-spacing値によってオフセットされ、[Zファイティング(z-fighting)](https://en.wikipedia.org/wiki/Z-fighting)を回避します。
* *Use single submesh* ：　1つのマテリアルのみを使用し、1つのサブメッシュのみを必要とする前提の場合に、サブメッシュの生成を簡素化するために有効にすることができます。これは、複数マテリアルの使用、レンダリングの分割、カスタムスロットマテリアルを無効にします。
* *Fix Prefab Override MeshFilter* ：　Prefabが常に変更されたものとしてマークされるのを修正します（`MeshFilter` の非表示フラグを `DontSaveInEditor` に設定）。 ただし、他のコンポーネントからの `MeshFilter` への参照は失われます。`Use Global Settings`  が設定されている場合、[Spine Preferences](/spine-unity-assets#Spine-Preferences)の設定が使用されます。
* *Threaded Mesh Generation*
	* *Use Threading* ：　有効にすると、アニメーションは複数のスレッドで並行して実行され、コンポーネントは共有の `SkeletonUpdateSystem` に登録されます。`Use Global Settings` が設定されている場合、[Spine Preferences](/spine-unity-assets#Spine-Preferences) の設定が使用されます。

![](/img/spine-runtimes-guide/spine-unity/z-spacing-small.gif)

* *PMA Vertex Colors* ：　頂点カラーRGBと頂点カラーアルファを乗算します。レンダリングに使用されているシェーダーがSpineシェーダー(`ストレートアルファテクスチャ`を使用している場合も)またはPMAのAdditive(加算)ブレンドモード `Blend One OneMinusSrcAlpha` を使用するサードパーティ製シェーダーの場合、このパラメーターを有効にしてください。通常のブレンドモード `Blend SrcAlpha OneMinusSrcAlpha` を伴う通常のシェーダーの場合は、このパラメーターを無効にしてください。有効にすると、加算スロットを通常スロットと一緒に1回のドローコールでレンダリングできます。無効にすると、加算スロットのために [`SkeletonData`](/spine-unity-assets#Skeleton-Data) の *Blend Mode Materials - Apply Additive Material* を有効にする必要があり、このために別のドローコールが必要になってしまうので、パフォーマンスに悪影響を与える可能性があります。
* *Tint Black (!)* ：　ブラックティントの頂点データをメッシュに追加します。スケルトンの中にティントブラックが設定されたスロットがあれば有効にしてください。  
ブラックティントは、この効果が機能するために、シェーダーがUV2とUV3をブラックティントカラーとして解釈する必要があります。そのために付属の `Spine/Skeleton Tint Black` シェーダーを使用することができます。個々のパーツではなくスケルトン全体を着色する必要がある場合は、効率が良く、MaterialPropertyBlockで `_Black` マテリアルプロパティを変更およびアニメーションさせることができる `Spine/Skeleton Tint` シェーダーをお勧めします。詳しくは[シェーダー](/spine-unity-rendering#シェーダー)セクションを参照してください。複数のスケルトンを異なる方法でティントする際にバッチングを維持するには[Skeleton.R .G .B .Aによるティント](/spine-unity-rendering#インスタンスごとにマテリアルを変更する)をお勧めします。
* *Add Normals* ：　有効にすると、メッシュジェネレーターは出力メッシュに法線を追加します。使用するシェーダーが頂点法線を必要とする場合に有効にしてください。パフォーマンスを向上させ、メモリ使用量を削減するには、代わりに `Spine/Skeleton Lit` シェーダーのような、希望する法線を想定するシェーダーを使用することができます。`Spine/Sprite` シェーダーは `Fixed Normal` を仮定するようにも設定できることに注意してください。
* *Solve Tangents* ：　一部のライトシェーダーは、通常、ノーマルマップ(法線マップ)を適用するために、頂点接線を必要とします。有効にすると、毎フレームで接線が計算され、出力メッシュに追加されます。
* *Physics Inheritance* ：　トランスフォームの動きをスケルトンの物理コンストレイントに適用する方法を制御します。
	* *Position* ：　ゼロ以外に設定すると、X方向およびY方向のトランスフォームの位置移動がスケルトンの物理コンストレイントに適用され、ここで設定したXおよびYのスケール係数で乗算されます。一般的な組み合わせは以下の通りです：  
		(1,1) にした場合、XY移動が通常通り適用されます。  
		(2,2) にした場合、XY移動が倍の強さで適用されます。  
		(1,0) にした場合、水平方向の移動だけが適用されます。  
		(0,0) にした場合、トランスフォームの移動の動きは全く適用されなくなります。
	* *Rotation* ：　ゼロ以外に設定すると、トランスフォームの回転の動きがスケルトンの物理コンストレイントに適用され、ここで設定したスケール係数で乗算されます。一般的な値は以下の通りです：  
		1 にした場合、通常通り適用されます。  
		2 にした場合、倍の強さで適用されます。  
		0 にした場合、トランスフォームの回転の動きは全く適用されなくなります。
	* *Movement relative to* 親トランスフォームなどに対する相対的なトランスフォームの動きを適用するには、これを動きを計算する基準となるトランスフォームに設定します。*None* に設定すると、ワールドの絶対位置*（デフォルト）*を使用します。
* *Add Skeleton Utility* ：　このボタンを使用すると、ボーンの位置をトラッキングしたり、オーバーライドしたりするための `SkeletonUtility` コンポーネントをGameObjectに素早く追加することができます。詳しくは[SkeletonUtility](/spine-unity-utility-components#SkeletonUtility)を参照してください。
* *Debug* ：　ゲームの実行中にスロットの現在のカラーやボーンのスケール値などの情報を知りたい時は、*Debug*ボタンを押せばデバッグ用の*Skeleton Debug*ウィンドウを開けます。ここで、ボーン、スロット、コンストレイント、表示順序、イベント、スケルトンの統計情報などの現在の状態を確認することができます。

![](/img/spine-runtimes-guide/spine-unity/debug-window.png)

## Skeleton

[SkeletonRenderer](#SkeletonRendererコンポーネント)コンポーネントは`SkeletonRenderer.Skeleton` プロパティを通じて、基盤となる[Skeleton](/spine-using-runtimes#Skeleton)へのアクセスを提供します。このSkeletonにより、スキンの設定、アタッチメントの追加、ボーンのリセットによるポーズやスケールの設定、スケルトン全体の反転操作が可能となります。

### アタッチメントの設定
アタッチメントを設定するには、スロットとアタッチメント名を入力します。

```csharp
bool success = skeletonRenderer.Skeleton.SetAttachment("slotName", "attachmentName");
```
```csharp
// プロパティを使用する場合
[SpineSlot] public string slotProperty = "slotName";
[SpineAttachment] public string attachmentProperty = "attachmentName";
...
bool success = skeletonRenderer.Skeleton.SetAttachment(slotProperty, attachmentProperty);
```
上記コード中の `[SpineSlot]` と `[SpineAttachment]` は、[こちらのセクション](#stringのプロパティ属性のスクリプティング)で説明している[Stringのプロパティ属性(Attribute)](#stringのプロパティ属性のスクリプティング)です。

### セットアップポーズへのリセット
[プロシージャルなアニメーション](/spine-runtime-skeletons#プロシージャルアニメーション)では、ボーンやスロットをセットアップのポーズに戻すことが必要な場合があります。[スキン](/spine-runtime-skins)を設定した後は、後述の[スキンの設定](#スキンの設定)セクションで説明するように [`Skeleton.SetupPoseSlots`](/spine-runtime-skins#スキンの変更) を呼び出す必要があるケースが多いでしょう。

```csharp
skeleton.SetupPose();
skeleton.SetupPoseBones();
skeleton.SetupPoseSlots();
```

### スキンの設定
Spineスケルトンは、どのアタッチメントをどのスロットに装着するかを定義する複数の[スキン](/spine-runtime-skins)を持っている場合があります。Skeletonコンポーネントは、スキンを切り替える簡単な方法を提供します。

```csharp
bool success = skeletonRenderer.Skeleton.SetSkin("skinName");
skeletonRenderer.Skeleton.SetupPoseSlots(); // 後述の補足を参照
```
```csharp
// プロパティを使用する場合
[SpineSkin] public string skinProperty = "skinName";
...
bool success = skeletonRenderer.Skeleton.SetSkin(skinProperty);
skeletonRenderer.Skeleton.SetupPoseSlots(); // 後述の補足を参照
```

以前に設定したアタッチメントが現在のアタッチメントの表示に影響するのを避けたい場合、スキンを変更した後に `Skeleton.SetupPoseSlots` を呼び出す必要があります。詳細は[こちら](/spine-runtime-skins#スキンの変更)のドキュメントを参照してください。

### スキンの組み合わせ
Spineスキンは組み合わせることが可能です。例えば、衣装アイテムスキンを組み合わせて完全なキャラクタースキンを形成することができます。
詳細は、[新しいSkin APIドキュメント](/blog/Spine-3-8-released#改善されたスキンAPI)をご覧ください。

```csharp
var skeleton = skeletonRenderer.Skeleton;
var skeletonData = skeleton.Data;
var mixAndMatchSkin = new Skin("custom-girl");
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("skin-base"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("nose/short"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("eyelids/girly"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("eyes/violet"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("hair/brown"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("clothes/hoodie-orange"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("legs/pants-jeans"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("accessories/bag"));
mixAndMatchSkin.AddSkin(skeletonData.FindSkin("accessories/hat-red-yellow"));
skeleton.SetSkin(mixAndMatchSkin);
skeleton.SetupPoseSlots();
skeletonAnimation.AnimationState.Apply(skeletonRenderer.Skeleton); // SkeletonMecanimの場合は skeletonMecanim.Update() を使用してください
```

#### ランタイムでの再パッキング

スキンを組み合わせると、複数のマテリアルが蓄積されることがあります。しかしこれは、ドローコールの増加につながってしまいます。
`Skin.GetRepackedSkin()`メソッドを使えば、収集したスキンに使用されているテクスチャ領域を、実行時に単一のテクスチャにまとめることができます。
```csharp
using Spine.Unity.AttachmentTools;

AtlasUtilities.RepackAttachmentsOutput repackingOutput; // これをMonoBehaviour のメンバーとして追加してください

// 前回の再パック処理のクリーンアップを行います。
// 注意：以前の GetRepackedSkin() 呼び出しで返されたマテリアルやテクスチャは 'new Texture2D()' と同様の挙動をするため、
// 破棄(destroy)を行う必要があります。また、この呼び出しを OnDestroy にも追加してください。
repackingOutput.DestroyGeneratedAssets();

// 再パックされたスキンを作成します。
AtlasUtilities.RepackAttachmentsSettings settings = AtlasUtilities.RepackAttachmentsSettings.Default;
settings.UseSourceMaterialsFrom(skeletonAnimation.SkeletonDataAsset);
settings.maxAtlasSize = 1024; // 必要に応じて他の設定も変更してください。
Skin repackedSkin = collectedSkin.GetRepackedSkin("Repacked skin", settings, ref repackingOutput); 

// 再パックされたスキンを使用します。
skeletonRenderer.Skeleton.Skin = repackedSkin;
skeletonRenderer.Skeleton.SetupPoseSlots();
skeletonAnimation.AnimationState.Apply(skeletonRenderer.Skeleton); // SkeletonMecanimの場合はskeletonMecanim.Update()

// オプションとして、複数の再パック操作後にキャッシュをクリアすることができます。
AtlasUtilities.ClearCache();
```

> **重要な注意事項:**  再パッキングに失敗したり、予期せぬ結果になる場合は、以下の原因が考えられます。:  
> 1. Read/Writeが無効になっている ：　プラットフォームの性能によっては、再パックされたテクスチャに結合されるソーステクスチャに `Read/Write Enabled` パラメーターを設定する必要があります。
> 2. Compressionが有効になっている ：　プラットフォームによっては、ソーステクスチャのテクスチャインポート設定の `Compression` が `Normal Quality` ではなく`None` に設定されていることを確認してください。
> 3. Qualityの設定で、半分または1/4の解像度のテクスチャを使用している ：　半分または1/4の解像度のテクスチャが使用されている場合、正しくない領域がコピーされるというUnityの既知のバグがあります。Project SettingsのQualityの設定がすべてフル解像度のテクスチャを使用していることを確認してください。
> 4. ソーステクスチャが2のべき乗になっていなくてもUnityがそれを最も近い累乗に拡大している ：　このため、a)[パック設定](/spine-texture-packer#設定)の `Power of two(2のべき乗)` を有効にしてSpineからエクスポートするか、b)Unityのアトラステクスチャのインポート設定で `Non-Power of Two` が `None` になっていることを確認してください。

さらに深く理解するには、サンプルシーンの `Spine Examples/Other Examples/Mix and Match` と `Spine Examples/Other Examples/Mix and Match Equip`、そして使用されている `MixAndMatch.cs` のサンプルスクリプトを参考にしてください。

#### 高度な情報 - ノーマルマップと一緒にランタイムで再パッキングする

メインテクスチャと一緒に、ノーマルマップ(法線マップ)やその他の追加テクスチャレイヤーを再パックすることもできます。
`settings.additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("_BumpMap") };` と設定することで、メインテクスチャとノーマルマップレイヤーの両方を再パックできます。また、出力用の構造体を準備するために、 `repackingOutput.additionalOutputTextures = new Texture2D[1];` を一度だけ代入してください。

```csharp
AtlasUtilities.RepackAttachmentsSettings settings;
AtlasUtilities.RepackAttachmentsOutput repackingOutput;

if (repackingOutput.additionalOutputTextures == null)
    repackingOutput.additionalOutputTextures = new Texture2D[1];

if (settings.additionalTexturePropertyIDsToCopy == null) {
    settings = AtlasUtilities.RepackAttachmentsSettings.Default;
    settings.UseSourceMaterialsFrom(skeletonAnimation.SkeletonDataAsset);
    settings.maxAtlasSize = 2048;
    settings.additionalTexturePropertyIDsToCopy = new int[] { Shader.PropertyToID("_BumpMap") };
    // settings.additionalTextureIsLinear と .additionalTextureFormats のデフォルト値はすでにノーマルマップに適したものになっています
}
Skin repackedSkin = prevSkin.GetRepackedSkin("Repacked skin", settings, ref repackingOutput);
prevSkin.Clear();

// 再パックされたスキンを使用します。
skeletonRenderer.Skeleton.Skin = repackedSkin;
skeletonRenderer.Skeleton.SetupPoseSlots();
skeletonAnimation.AnimationState.Apply(skeletonRenderer.Skeleton); // SkeletonMecanimの場合はskeletonMecanim.Update()
```

> **注意:**　通常、ノーマルマップ(法線マップ)のプロパティは `"_BumpMap"` という名前になっていますが、カスタムシェーダーを使用する場合は、必ずそれぞれのプロパティ名を使用してください。なお、この名前はシェーダー内のプロパティ名であり、Inspectorに表示される `"Normal Map"` ラベル文字列ではないことに注意してください。

### アトラステクスチャのオンデマンドローディング

スケルトンごとに多くのスキンとアトラスページテクスチャが必要になる場合、全てのアトラステクスチャは[SkeletonDataAsset](/spine-unity-assets#SkeletonDataAsset)によって間接的に参照されるため、スケルトンがロードされるときに全てロードされることに注意する必要があります。これは標準的なUnityのロード挙動に従っています。

メモリ使用量とアプリケーションのダウンロードサイズを最適化するために、[オンデマンドローディングUPMパッケージ](/spine-unity-on-demand-loading)を使用して、テクスチャを実行時に動的にロードすることができます。これにより、[Unity Addressables](https://learn.unity.com/course/get-started-with-addressables)のようなシステムと統合して、対応するスキンが割り当てられたときにのみ高解像度のアトラステクスチャをダウンロードすることが可能になります。これにより、実行時にわずかなロード遅延は発生しますが、初期ロードサイズを削減できます。

### スケルトンのスケール変更と反転
スケルトンを垂直または水平方向に反転させることで、アニメーションを再利用することができます。例えば、左向きの歩行アニメーションを右向きにして再生することができます。

```csharp
bool isFlippedX = skeleton.ScaleX < 0;
skeleton.ScaleX = -1;
bool isFlippedY = skeleton.ScaleY < 0;
skeleton.ScaleY = -1;

skeleton.ScaleX = -skeleton.ScaleX; // x反転の状態を切り替え
```

### ボーントランスフォームへの手動アクセス

> **注意:**　**こちらは非常に特殊なケースでのみ使用することをお勧めします。** Spineの[BoneFollower](/spine-unity-utility-components#BoneFollower)や[SkeletonUtilityBone](/spine-unity-utility-components#SkeletonUtilityBone)コンポーネントの方がより簡単にボーンを操作することができます。

Skeletonでは、ボーンのトランスフォーム値を設定・取得できるので、IKによる地形追従を実装したり、パーティクルシステムなどの他のアクターやコンポーネントをスケルトンのボーンに追従させることができます。

> **注意:**　[`SkeletonAnimation.UpdateWorld`](#ライフサイクル)デリゲートをサブスクライブすることで、ワールドトランスフォームの更新のライフサイクルの一部として新しいボーンの位置を取得して適用するようにしてください。そうしないと、ロード時に修正が1フレーム遅れたり、設定したときにアニメーションによって上書きされたりする可能性があります。

```csharp
Bone bone = skeletonRenderer.Skeleton.FindBone("boneName");
Vector3 worldPosition = bone.GetWorldPosition(skeletonRenderer.transform);
// 注意：SkeletonGraphicを使用する場合、すべての値は親のCanvas.referencePixelsPerUnitでスケーリングする必要があります。

Vector3 position = ...;
bone.SetPositionSkeletonSpace(position);

Quaternion worldRotationQuaternion = bone.GetQuaternion();
```

### ライフサイクル

[SkeletonRenderer](#SkeletonRendererコンポーネント)コンポーネントにおいて、スケルトンは全てのボーン、スキン、アタッチメント、コンストレイントなどの状態を保持しています。`LateUpdate` ごとに、使用されているMeshRenderer上のメッシュとマテリアルが更新され、現在のスケルトンポーズがレンダリングされます。

#### C# #

スクリプトは、SkeletonRendererの `LateUpdate` の前後いずれかのタイミングで実行できます。SkeletonRendererのLateUpdate前にマテリアルを変更するコードを記述した場合、SkeletonRendererによる後続の変更によって変更内容が上書きされ、結果として効果が得られない可能性があります。

[SkeletonRenderer](#SkeletonRendererコンポーネント)コンポーネントおよび [SkeletonGraphic (UI)](#SkeletonGraphicコンポーネント) コンポーネントは、このライフサイクルを適切なタイミングで捕捉できるコールバックデリゲートをプロパティとして公開しています。これらのデリゲートにバインドすることで、コンポーネントの更新順序を気にすることなく、マテリアルやスケルトンのその他の側面を変更することが可能です。

SkeletonRendererの更新コールバック
- `OnRebuild` は、スケルトンの初期化が正常に完了した後に発生します。
- `OnMeshAndMaterialsUpdated` は、`LateUpdate()` の終了時、メッシュおよび全てのマテリアルが更新された後に発生します。

```csharp
// OnMeshAndMaterialsUpdated用のデリゲートメソッド
void AfterMeshAndMaterialsUpdated (SkeletonRenderer renderer) {
	// これはメッシュとマテリアルが更新された後に呼び出されます。
}

// OnRebuild用のデリゲートメソッド
void AfterRebuild (SkeletonRenderer renderer) {
	// これはスケルトンの初期化が正常に完了した後に呼び出されます。
}

// デリゲートメソッドの登録
void Start() {
	skeletonRenderer.OnMeshAndMaterialsUpdated -= AfterMeshAndMaterialsUpdated;
	skeletonRenderer.OnMeshAndMaterialsUpdated += AfterMeshAndMaterialsUpdated;

	skeletonRenderer.OnRebuild -= AfterRebuild;
	skeletonRenderer.OnRebuild += AfterRebuild;
}
```

ボーンおよびアニメーション関連の追加コールバックデリゲートについては、SkeletonAnimationセクション内の[ライフサイクル](#ライフサイクル2)を参照してください。

別の方法として、[スクリプトの実行順序](#スクリプトの実行順序) を変更して、SkeletonRendererのLateUpdateメソッドの後に実行されるように設定することもできます。

## SkeletonAnimationコンポーネント

`SkeletonAnimation` コンポーネントは、UnityでSpineスケルトンをアニメーションさせるために使用される2つのアニメーションコンポーネントのうちの1つで、もう1つは[SkeletonMecanim](#SkeletonMecanimコンポーネント)です。レンダラーコンポーネントが必要であり、通常、スケルトンの管理とレンダリングを行う[SkeletonRenderer](#SkeletonRendererコンポーネント)コンポーネントと組み合わせて使用されます。

SkeletonAnimationコンポーネントを使用することで、Spineスケルトンをアニメーションさせたり、アニメーションイベントへ反応させることができます。

![](/img/spine-runtimes-guide/spine-unity/skeleton-animation-component-43.png)

### プロパティ

[SkeletonAnimation](#SkeletonAnimationコンポーネント)のInspectorは以下のパラメーターを公開しています ：
* *Animation Name* ：　ここで設定したアニメーションがスタート時に再生されます。
* *Loop* ：　初期アニメーションをループさせるか、一度だけ再生するかを定義します。
* *Time Scale* ：　ここでタイムスケールを設定することで、アニメーションの再生を遅くしたり、速くしたりすることができます。
* *Unscaled Time* ：　`true` に設定すると、アップデートが [Time.deltaTime](https://docs.unity3d.com/ScriptReference/Time-deltaTime.html) の代わりに [Time.unscaledDeltaTime](https://docs.unity3d.com/ScriptReference/Time-unscaledDeltaTime.html)  に従って実行されます。これはスローモーションなどの影響を受けずに独立したUI要素をアニメーションさせたい場合などに便利です。
* *Animation Update* ：　アニメーションの更新タイミングについて、通常の`Update` *(デフォルト)*、物理ステップの `FixedUpdate`、またはユーザーによる手動呼び出しのいずれで行うかを設定します。[SkeletonRootMotion](/spine-unity-utility-components#SkeletonRootMotion)コンポーネントを使用し、`Rigidbody` または `Rigidbody2D` が割り当てられている場合は、更新モードを `In FixedUpdate` に設定することをお勧めします。それ以外の場合は `In Update` が推奨されます。
* *Threaded Animation*
	* *Use Threading* ：　有効にすると、アニメーションはマルチスレッドで並行して実行され、コンポーネントは共有の `SkeletonUpdateSystem` に登録されます。`Use Global Settings` に設定された場合、[Spine Preferences](/spine-unity-assets#Spine-Preferences) の設定が使用されます。
* *Root Motion - Add Component* ：　後述の手順の通り、GameObject `SkeletonRootMotion` コンポーネントを追加することで、ルートモーションを有効にします。

### ルートモーションの有効化

`SkeletonAnimation` および [SkeletonGraphic (UI)](#SkeletonGraphicコンポーネント)コンポーネントのルートモーションは、別途用意された [SkeletonRootMotion](/spine-unity-utility-components#SkeletonRootMotion) コンポーネントを通じて提供されます。`SkeletonAnimation` のInspectorには、そのスケルトンGameObjectに適切なコンポーネントを素早く追加するための `Root Motion` `Add Component` ボタンが用意されています。

### ライフサイクル
![](/img/spine-runtimes-guide/spine-unity/spine-unity-skeletonanimation-updates.png)  
[SkeletonAnimation](#SkeletonAnimationコンポーネント)コンポーネントでは、AnimationStateが現在再生中のアニメーションやキューに登録されている全てのアニメーションのステート(状態)を保持しています。
AnimationStateは `Update` ごとに更新され、アニメーションが時間軸に沿って進行します。そして、新しいフレームが新しいポーズとしてスケルトンに適用されます。

#### C# #
コードを介してスケルトンとやり取りするには、SkeletonAnimation コンポーネントまたは SkeletonRenderer コンポーネントにアクセスする必要があります。Unityコンポーネント全般に当てはまることですが、参照を一度取得し、今後の使用のために保存しておくことをお勧めします。

```csharp
...
using Spine.Unity;

public class YourComponent : MonoBehaviour {

	SkeletonAnimation skeletonAnimation;
	Spine.AnimationState animationState;
	Spine.Skeleton skeleton;

	void Awake () {
		skeletonAnimation = GetComponent<SkeletonAnimation>();
		skeleton = skeletonAnimation.Skeleton;
		//skeletonAnimation.Initialize(false); // skeletonAnimation.Skeletonにアクセスしていない場合は、
											// Initialize(false)を使用して、すべてのものがロードされていることを確認します。
		animationState = skeletonAnimation.AnimationState;
	}
```

スクリプトは、SkeletonAnimationの `Update` の前でも後でも実行できます。
あなたのコードがSkeletonAnimationのUpdateの前にスケルトンまたはボーンの値を取得する場合、コードは現在のフレームではなく前のフレームから値を読み取ります。

このコンポーネントは、イベントコールバックデリゲートをプロパティとして公開しており、すべてのボーンのワールドトランスフォームが計算される前と後に、このライフサイクルをインターセプトすることができます。これらのデリゲートにバインドすることで、アクターやコンポーネントの更新順序を気にすることなく、ボーンの位置やスケルトンの他の側面を修正することができます。

SkeletonRendererとSkeletonAnimationのUpdateコールバック
- `SkeletonAnimation.BeforeApply` は、そのフレームのアニメーションが適用される前に発生します。このコールバックは、アニメーションが適用される前にスケルトンの状態を変更したい場合に使用します。
- `SkeletonRenderer.UpdateLocal` は、そのフレームのアニメーションが更新され、スケルトンのローカル値に適用された後に発生します。ボーンのローカル値を読み込んだり修正したりする必要がある場合に使用します。
- `SkeletonRenderer.UpdateComplete` は、Skeletonのすべてのボーンに対してワールド値が計算された後に発生します。SkeletonAnimationは、この後、Update内でそれ以上の操作をしません。ボーンのワールド値を読み取る必要がある場合は、これを使用してください。正、これらの値は、SkeletonAnimationのUpdate後にスクリプトが変更すると、まだ変更される可能性があります。
- `SkeletonRenderer.UpdateWorld` は、Skeletonのすべてのボーンに対してワールド値が計算された後に発生します。このイベントをサブスクライブすると、`skeleton.UpdateWorldTransform` が再度呼び出されます。スケルトンの複雑さやあなたがやっていること次第では、これは不要であったり、非効率的な可能性があります。このイベントは、ボーンのワールド値に基づいて、ボーンのローカル値を修正する必要がある場合に使用します。これは、Unityのコードでカスタムコンストレイントを実装するのに便利です。

```csharp
// あなたのデリゲートメソッド
void AfterUpdateComplete (ISkeletonAnimation anim) {
	// これはアニメーションの更新が完了した後に呼び出されます
}

// あなたのデリゲートメソッドを登録
void Start() {
	skeletonRenderer.UpdateComplete -= AfterUpdateComplete;
	skeletonRenderer.UpdateComplete += AfterUpdateComplete;
}
```

別の方法として、[スクリプトの実行順序](#スクリプトの実行順序)を変更し、SkeletonAnimationのUpdateメソッドの後に実行されるように設定することも可能です。

#### スクリプトの実行順序

Unityでは、各コンポーネントの `Update` および `LateUpdate` の呼び出しはスクリプトの実行順に従って順序付けられます(詳しくは[イベント関数の実行順序](https://docs.unity3d.com/ja/current/Manual/ExecutionOrder.html)および [`DefaultExecutionOrder`](https://docs.unity3d.com/6000.0/Documentation/ScriptReference/DefaultExecutionOrder.html) を参照してください)。ご自身のコンポーネントの `Update` または `LateUpdate` メソッドから呼び出しを行ってスケルトンやアニメーションの状態を変更する場合は、SkeletonAnimationコンポーネントに関連して適切なタイミングで実行することが重要です。

SkeletonRendererおよびSkeletonAnimationの更新順序は以下の通りです:
- **`SkeletonAnimation.Update`**: アニメーションを更新し、アニメーションをスケルトンに適用します。
- **`SkeletonRenderer.LateUpdate`**: スケルトンの状態に基づいてスケルトンメッシュを更新します。

スケルトンの状態を変更するには:
- *アニメーションが適用されるよりも前*に実行するには、`Update` から呼び出しを行い、実行順を*SkeletonAnimationの前*に設定してください。
- *アニメーションが適用された後*、スケルトンメッシュが生成される前に実行するには、`Update` から呼び出しを行い、実行順序を*スケルトンアニメーションの後*に設定してください。あるいは、`LateUpdate` から呼び出しを行い、実行順序をスケルトンアニメーションの*前*に設定することも可能です。

```csharp
// 実行順序が-1の場合、このコンポーネントはSkeletonAnimationとSkeletonRendererの前に実行されます。
[DefaultExecutionOrder(-1)]
public class SetupPoseComponent : MonoBehaviour {
	...

	void Update() {
		// この呼び出しにより、アニメーションを適用する前に、スケルトンが各フレームでセットアップポーズから開始されます。
		// SetupPoseComponent.Updateは、SkeletonAnimation.Updateの前に呼び出される必要があります。
		// これは、上記の[DefaultExecutionOrder(-1)]によって保証されています。
		skeleton.SetupPose();
	}
}
```

スクリプトの実行順序を変更できない場合、後述の[手動アップデート](#手動アップデート)の手順に従って手動でアップデートを行うことで、同じフレーム内のスケルトンまたはスケルトンメッシュを更新することができます。

#### 手動アップデート

特定の修正を行った後、スケルトンにアニメーションをすぐに再適用したり、修正したスケルトンに基づいてスケルトンメッシュを再生成したい場合があります。[汎用ランタイム](https://esotericsoftware.com/spine-runtime-skeletons)とは異なり、SkeletonAnimationコンポーネントは、単一のメソッド呼び出しで一貫した更新を可能にする追加のメソッドを提供しています。 例えば、`skeleton.UpdateWorldTransform()` は、下記の `Update(deltaTime)` および `ApplyAnimation()` の一部として呼び出されます。

- **`Update(deltaTime)`** を実行すると、スケルトン全体が更新されます。スケルトンメッシュは変更されません。  
`SkeletonAnimation.Update(deltaTime)` は `AnimationState` を更新し、このフレームのトランスフォームの動きを物理コンストレイントに伝達し、スケルトンにアニメーションを適用します。その後、すべてのボーンのワールドトランスフォームが更新されます。これは、時間を進めずにスケルトン全体を更新する必要がある場合や、カスタムのデルタタイムで進めたい場合に必要となる場合があります。

```csharp
// ポーズを設定するためにボーンとスロットを設定した後、時間を進めずにスケルトン全体の更新を実行します。 
skeleton.SetupPose();
skeletonAnimation.Update(0);

// 通常、ポーズを設定するスロットのみを設定する場合は(アクティブなスキンボーンが変更される場合を除いて)、
// ボーンのワールドトランスフォームの更新は必要ないので、AnimationState.Apply(skeleton)で十分です。
skeleton.SetupPoseSlots();
skeletonAnimation.AnimationState.Apply(skeleton)
```

```csharp
// UnityのTime.deltaTimeやunscaledDeltaTimeではなく、カスタムのデルタタイムで進めたい場合。
skeletonAnimation.timeScale = 0f;
...
skeletonAnimation.Update(customDeltaTime);
```

- **`ApplyAnimation()`** はスケルトンにアニメーションを再適用します。  
`SkeletonAnimation.ApplyAnimation()` も同様にスケルトンにアニメーションを再適用しますが、`AnimationState` を更新したり、トランスフォームの動きを物理コンストレイントに伝達したりすることはありません。

- **`UpdateMesh()`** はスケルトンメッシュをスケルトンの状態に基づいて更新します。  
`SkeletonRenderer.UpdateMesh()` は、スケルトンを基にスケルトンメッシュを更新します。(`SkeletonRenderer.LateUpdate()` と似ていますが、こちらは `UpdateMode` を無視します。)これは、`LateUpdate()` 内でスケルトンのプロパティを修正したけれど、スクリプトの実行順序が遅すぎて `SkeletonAnimation.LateUpdate()` がすでにこのフレームのスケルトンメッシュを更新してしまった場合に、必要になることがあります。

```csharp
// スクリプトでLateUpdate()内のスケルトンプロパティを変更し、
// スクリプトの実行順がSkeletonAnimationより後になっている場合。
void LateUpdate () {
	skeleton.SetupPose(); // スケルトンを修正する
	skeletonAnimation.Update(0);
	skeletonAnimation.UpdateMesh(); // これが無いと、SkeletonAnimation.LateUpdateの呼び出しは次のフレームになります。
}
```

## アニメーション - AnimationState

### ライフサイクル

[SkeletonAnimation](#SkeletonAnimationコンポーネント)コンポーネントは `Update` メソッドを実装しています。このメソッドでは、デルタタイムに基づいて基礎となる[AnimationState](/spine-applying-animations#AnimationState-API)を更新し、その`AnimationState`をスケルトンに適用し、スケルトンのすべてのボーンのワールドトランスフォームを更新します。

SkeletonAnimationコンポーネントは、`SkeletonAnimation.AnimationState` プロパティを介して[AnimationState](/spine-api-reference#AnimationState)APIを公開しています。このセクションでは、トラック、TrackEntry、ミックスタイム、アニメーションのキューイングなどの概念について、全般的なSpineランタイムガイドの[アニメーションの適用](/spine-applying-animations)の項で説明されている内容を前提としています。

### タイムスケール
SkeletonAnimationコンポーネントのタイムスケールを設定することで、アニメーションの再生を遅くしたり、速くしたりすることができます。例えば、タイムスケールが0.5の場合、アニメーションは通常の半分の速度になり、タイムスケールが2の場合、アニメーションは通常の2倍の速度になるというように、アニメーションの進行に使用されるデルタタイムは、単純にタイムスケールを乗じたものになります。

```csharp
float timeScale = skeletonAnimation.timeScale;
skeletonAnimation.timeScale = 0.5f;
```

### アニメーションの設定

アニメーションを設定するには、トラックのインデックス、アニメーション名、アニメーションをループさせるかどうかを指定します。

```csharp
TrackEntry entry = skeletonAnimation.AnimationState.SetAnimation(trackIndex, "walk", true);
```
```csharp
// プロパティを使用する場合
[SpineAnimation] public string animationProperty = "walk";
...
TrackEntry entry = skeletonAnimation.AnimationState.SetAnimation(trackIndex, animationProperty, true);
```
別の方法として、文字列ではなく[AnimationReferenceAsset](/spine-unity-assets#Preview)をパラメーターとして使用することもできます。
```csharp
// AnimationReferenceAssetを使用する場合
public AnimationReferenceAsset animationReferenceAsset; // 生成された AnimationReferenceAsset をこのプロパティに割り当てます。
...
TrackEntry entry = skeletonAnimation.AnimationState.SetAnimation(trackIndex, animationReferenceAsset, true);
```

現在のアニメーションが変更されると、自動的にミキシング（クロスフェード）が適用され、連続する2つのアニメーション間のスムーズな移行が行われます。空のトラックにアニメーションをミックスインまたはミックスアウトしたい場合は、「[空のアニメーションとクリア処理](#空のアニメーションとクリア処理)」を参照してください。

> **重要な注意事項: フレームごとに `SetAnimation` を呼び出さないようにしてください。** spine-unityランタイムがアニメーションが変更されたかどうかを自動的に検出してくれるだろうと期待して、スクリプトの `Update` メソッドで対象のアニメーションがすでに再生されているかどうかに関係なく `SetAnimation` を呼び出したくなるかもしれませんが、そのようにすると各フレームでアニメーションが新しく開始され、アニメーションが最初のフレームでフリーズしてしまいます。また、Spineランタイムはアニメーション間でスムーズな遷移ができるように設計されているため、そのようにすると呼び出しごとに[TrackEntry](/spine-api-reference#TrackEntry)を追加し、同じトラック上にあるアニメーションから新しく追加されたアニメーションまでをミックスしようとしてしまいます。
>
> 毎フレーム `SetAnimation` を呼び出す代わりに、キャラクターの現在の状態を記録して、別のアニメーションに変更するときだけ `SetAnimation` を呼び出すようにしてください。ボタンを長押ししている間など、アニメーションを最初のフレームで維持したい場合は、代わりに [TrackEntry.trackTime](/spine-api-reference#TrackEntry-trackTime) を設定してください。これができない場合は、[AnimationState.ClearTrack](/spine-api-reference#AnimationState-clearTrack) を使用して、新しいアニメーションを設定する前に、同じトラック上のすべてのアニメーションをクリアしてください。

#### アニメーションのキューイング
アニメーションをキューに追加するには、トラックのインデックス、アニメーション名、アニメーションをループさせるかどうか、このアニメーションがトラックで再生を開始するまでの遅延時間を秒単位で指定します。

```csharp
TrackEntry entry = skeletonAnimation.AnimationState.AddAnimation(trackIndex, "run", true, 2);
```
```csharp
// プロパティを使用する場合
[SpineAnimation] public string animationProperty = "run";
...
TrackEntry entry = skeletonAnimation.AnimationState.AddAnimation(trackIndex, animationProperty, true, 2);
```

### 空のアニメーションとクリア処理

トラックにアニメーションが何も設定されていない時に新しくアニメーションが設定された場合、再生がすぐに開始されます。トラックがクリアされると、トラックのアニメーションは適用されなくなり、スケルトンは現在のポーズのままになります。1つのアニメーションをミックスインまたはミックスアウトするには、[総合的なランタイムガイド](/spine-applying-animations/#空のアニメーション)の中でも説明されているように、*空の*アニメーションを使用することができます。

SkeletonAnimationコンポーネントには、空のアニメーションを設定したり、空のアニメーションをキューに入れたり、1つまたはすべてのトラックをクリアするメソッドも用意されています。これらはすべて、上述のメソッドやノードと同様に動作します。

```csharp
TrackEntry entry = skeletonAnimation.AnimationState.SetEmptyAnimation(trackIndex, mixDuration);
entry = skeletonAnimation.AnimationState.AddEmptyAnimation(trackIndex, mixDuration, delay);
skeletonAnimation.AnimationState.ClearTrack(trackIndex);
skeletonAnimation.AnimationState.ClearTracks();
```

### TrackEntry
すべてのメソッドから[TrackEntry](/spine-api-reference#TrackEntry)を受け取り、特定のアニメーションの再生をさらにカスタマイズしたり、TrackEntryのイベントのデリゲートにバインドしたりすることができます。詳しくは後述の「*AnimationStateイベントの処理*」をご覧ください。

> **注意:**　返されたTrackEntryは、対応するアニメーションが根底となるAnimationStateから削除されるまでのみ有効です。Unityのガベージコレクターが自動的にこれらを解放します。TrackEntryのdisposeイベントを受け取った後は、もう保存もアクセスもしないようにしてください。

```csharp
TrackEntry entry = ...
entry.EventThreshold = 2;
float trackEnd = entry.TrackEnd;
```

### AnimationStateイベントの処理
アニメーションが `AnimationState` によって再生されている間、様々なイベントが発行され、リスナーに以下を通知します。

1. アニメーションが**開始された(start)**。
2. トラックをクリアしたり、新しいアニメーションを設定するなどして、アニメーションが**中断された(interrupt)**。
4. 途切れることなくアニメーションが**完了した(complete)**。※ループしている場合は複数回発生
3. アニメーションが**終了した(end)**。
5. アニメーションとそれに対応する `TrackEntry` が**破棄された(dispose)**。
6. ユーザーが定義した**イベント(event)**が発生した。

> **補足:**　前のアニメーションを中断して新しいアニメーションを設定した場合、`complete` イベントは発生せず、代わりに `interrupt` と `end` イベントが発生します。

SkeletonAnimationコンポーネントは、すべてのトラックでキューイングされたすべてのアニメーションのイベントに反応するために、C#コードがバインドできるデリゲートを提供します。また、リスナーは特定の `TrackEntry` の対応するデリゲートにのみバインドすることもできます。例えば `AnimationState.Complete` に登録すればあらゆるアニメーションの `Complete` イベントで処理が実行され、`TrackEntry.Complete`に登録すれば特定のアニメーションによって発行された `Complete` イベントのみを処理することができます。

#### C# #
`AnimationState` イベントに反応するクラスで、取得したいイベントのデリゲートを追加します:

```csharp
SkeletonAnimation skeletonAnimation;
Spine.AnimationState animationState;
	
void Awake () {
	skeletonAnimation = GetComponent<SkeletonAnimation>();
	animationState = skeletonAnimation.AnimationState;
	
	// あらゆるアニメーションから発生されるイベントに対して登録する
	animationState.Start += OnSpineAnimationStart;
	animationState.Interrupt += OnSpineAnimationInterrupt;
	animationState.End += OnSpineAnimationEnd;
	animationState.Dispose += OnSpineAnimationDispose;
	animationState.Complete += OnSpineAnimationComplete;

	animationState.Event += OnUserDefinedEvent;

	// 特定のアニメーションのTrackEntryから発生されるイベントに対して登録する
	Spine.TrackEntry trackEntry = animationState.SetAnimation(trackIndex, "walk", true);
	trackEntry.Start += OnSpineAnimationStart;
	trackEntry.Interrupt += OnSpineAnimationInterrupt;
	trackEntry.End += OnSpineAnimationEnd;
	trackEntry.Dispose += OnSpineAnimationDispose;
	trackEntry.Complete += OnSpineAnimationComplete;
	trackEntry.Event += OnUserDefinedEvent;
}

public void OnSpineAnimationStart(TrackEntry trackEntry) {
	// startイベントに反応させたい実装コードをここに追加してください
}
public void OnSpineAnimationInterrupt(TrackEntry trackEntry) {
	// interruptイベントに反応させたい実装コードをここに追加してください
}
public void OnSpineAnimationEnd(TrackEntry trackEntry) {
	// endイベントに反応させたい実装コードをここに追加してください
}
public void OnSpineAnimationDispose(TrackEntry trackEntry) {
	// disposeイベントに反応させたい実装コードをここに追加してください
}
public void OnSpineAnimationComplete(TrackEntry trackEntry) {
	// completeイベントに反応させたい実装コードをここに追加してください
}


string targetEventName = "targetEvent";
string targetEventNameInFolder = "eventFolderName/targetEvent";

public void OnUserDefinedEvent(Spine.TrackEntry trackEntry, Spine.Event e) {
	
	if (e.Data.Name == targetEventName) {
		// ユーザー定義イベントに反応させたい実装コードをここに追加してください
	}
}

// イベントデータをキャッシュすることで、文字列の比較を省略することができます
Spine.EventData targetEventData;
void Start () {
	targetEventData = skeletonAnimation.Skeleton.Data.FindEvent(targetEventName);
}
public void OnUserDefinedEvent(Spine.TrackEntry trackEntry, Spine.Event e) {

	if (e.Data == targetEventData) {
		// ユーザー定義イベントに反応させたい実装コードをここに追加してください
	}
}
```

詳細は[Spine API Reference](/spine-api-reference#AnimationStateListener-Methods)をご覧ください。

#### コールバック内でのAnimationStateやゲームのステートの変更について

`AnimationState` のイベントコールバックから `AnimationState.SetAnimation()` を呼び出すなどして `AnimationState` を変更することができますが、ここには考慮すべき以下のようなタイミングの問題があります。これは、イベントコールバックからゲームステートを変更する場合にも当てはまります。

1. `AnimationState` イベントコールバックは `SkeletonAnimation.Update()` でアニメーションが適用されるときに発行され、`SkeletonAnimation.LateUpdate()` でメッシュが更新されるよりも前に発行されます。
2. [`AnimationState.End`](/spine-api-reference#AnimationStateListener-end)コールバックから `AnimationState.SetAnimation()` を呼び出すと、同じフレームで [`AnimationState.Start`](/spine-api-reference#AnimationStateListener-start) イベントがトリガーされます。
3. 1つのアニメーションから別のアニメーションへのミックストランジションのために、`Start` イベントは1つ目のアニメーションの `End` イベントよりも _前に_ 発行されます。これは、ゲームステートを変更するときに考慮すべきよくある落とし穴です。

このようなイベントコールバック内からの呼び出しを、次の `Update()` サイクルまで遅らせたい場合は、次のように `StartCoroutine` を使用してください：

```csharp
trackEntry.End += e => {
	StartCoroutine(NextFrame(() => {
		YourCode();
	}));
};

...

IEnumerator NextFrame (System.Action call) {
	yield return 0;
	if (call != null)
		call();
}
```

#### コルーチンのyield命令

spine-unityランタイムは、Unityのコルーチン(Coroutines)で使用するための一連のyield命令を提供しています。Unityのコルーチンを初めて使用される方は、[コルーチンのチュートリアル](https://unity3d.com/learn/tutorials/topics/scripting/coroutines)と[コルーチンのドキュメント](https://docs.unity3d.com/Manual/Coroutines.html)から始めることをお勧めします。

以下のようなyield命令があります:
1. **`WaitForSpineAnimation`** `Spine.TrackEntry` が指定されたイベントの1つを発生させるまで待機します。
	```csharp
	var track = skeletonAnimation.state.SetAnimation(0, "interruptible", false);
	var completeOrEnd = WaitForSpineAnimation.AnimationEventTypes.Complete |
	                            WaitForSpineAnimation.AnimationEventTypes.End;
	yield return new WaitForSpineAnimation(track, completeOrEnd);
	```

1. **`WaitForSpineAnimationComplete`**  `Spine.TrackEntry` が `Complete` イベントを発生させるまで待機します。
	```csharp
	var track = skeletonAnimation.state.SetAnimation(0, "talk", false);
	yield return new WaitForSpineAnimationComplete(track);
	```

1. **`WaitForSpineAnimationEnd`**. `Spine.TrackEntry` が `End` イベントを発生させるまで待機します。
	```csharp
	var track = skeletonAnimation.state.SetAnimation(0, "talk", false);
	yield return new WaitForSpineAnimationEnd(track);
	```

1. **`WaitForSpineEvent`**  `Spine.AnimationState` が、ユーザーが定義した `Spine.Event`(Spineエディター内で命名)を発生させるまで待機します。
	```csharp
	yield return new WaitForSpineEvent(skeletonAnimation.state, "spawn bullet");
	// Spine.EventのSpine.EventDataリファレンスを渡すこともできます。
	Spine.EventData spawnBulletEvent; // Start() などでキャッシュされます。
	..
	yield return new WaitForSpineEvent(skeletonAnimation.state, spawnBulletEvent);
	```
	
> **補足:**　Unityに組み込まれているyield命令と同様に、spine-unityのyield命令のインスタンスも再利用することができ、追加のメモリ割り当てを防ぐことができます。

#### チュートリアルページ

[こちら](/spine-unity-events)でspine-unityのイベントのチュートリアルページを確認できます。

### stringのプロパティ属性のスクリプティング

Inspectorでアニメーションの名前などを手入力するのは少し手間がかかります。そこでspine-unityは文字列(string)パラメーターのポップアップフィールドを提供します。`string` プロパティの前に以下のプロパティ属性(Attribute)のいずれかを指定すると、スケルトンで利用可能なすべてのアニメーションなどが入力されたポップアップ選択フィールドが自動的に表示されます。提供されているSpineコンポーネントにこのようなポップアップフィールドがある場合、カスタムコンポーネントでもプロパティ属性を使って同じポップアップを使用することができます。以下は利用可能なプロパティ属性の一覧です。


```csharp
[SpineBone] public string bone;
[SpineSlot] public string slot;
[SpineAttachment] public string attachment;
[SpineSkin] public string skin;
[SpineAnimation] public string animation;
[SpineEvent] public string event;
[SpineIkConstraint] public string ikConstraint;
[SpineTransformConstraint] public string transformConstraint;
[SpinePathConstraint] public string pathConstraint;
```

spine-unityパッケージに含まれる[サンプルシーン](/spine-unity-examples#サンプルシーン)で、stringプロパティ属性が使用されているのを確認してみてください。

## SkeletonGraphicコンポーネント

`SkeletonGraphic` コンポーネントは、Canvas UI におけるスケルトンの描画および現在の状態の管理を担当します。これは2つあるスケルトンのレンダリング用コンポーネントのうちの1つであり、もう1つは通常の非Canvas要素向けの[SkeletonRenderer](#SkeletonRendererコンポーネント)です。

`SkeletonGraphic` コンポーネントは、レイアウト、レンダリング、マスクの相互作用にUnityのUIシステムを利用しています。
スキンの設定やボーンの変更など、一般的なスケルトン操作については[SkeletonRenderer](#SkeletonRendererコンポーネント)と同様です。

![](/img/spine-runtimes-guide/spine-unity/skeleton-graphic-component-43.png)

#### なぜ特定のUIコンポーネントなのか

UnityのUI(UnityEngine.UI)は、`Canvas` と `CanvasRenderers` システムを使って、レンダリング可能なオブジェクトを分類・管理しています。`Text`、`Image`、`RawImage` などの組み込みのレンダリング可能なUIコンポーネントは `CanvasRenderer` に依存して正しく機能します。`MeshRenderers`（デフォルトのCubeオブジェクトなど）や `SpriteRenderers`（Spriteなど）のようなオブジェクトをUIの下に置くと、`Canvas` ではレンダリングされません。`SkeletonAnimation` は `MeshRenderer` を使用しているため、同様の挙動になります。そのため、spine-unityランタイムでは `UnityEngine.UI.MaskableGraphic` のサブクラスで `CanvasRenderer` コンポーネントをレンダリングに使用する `SkeletonAnimation` のvariantである `SkeletonGraphic` を提供しています。

### マテリアルの重要な要件

SkeletonGraphicコンポーネントでは、デフォルトで割り当てられている `Spine/SkeletonGraphic*` シェーダーなど、CanvasRenderer互換の特殊なシェーダーを持つマテリアルのみを使用してください。URP、LWRP、`Spine/Skeleton` のような通常のシェーダーを `SkeletonGraphic` コンポーネントで使用しないでください。視覚的なエラーが出ないからといって、そのシェーダーが `SkeletonGraphic` で動作するとは限りません。実際、Unityエディター上では問題なくレンダリングできるのにモバイルデバイスでは正しくレンダリングできないという事例が確認されています。他のUIコンポーネントと同様に、`SkeletonGraphic` は `MeshRenderer` ではなく `CanvasRenderer` を使用しており、別のレンダリングパイプラインを使用しています。

`SpineAtlasAsset` で割り当てられた通常のマテリアルは、`SkeletonDataAsset` を `SkeletonGraphic` としてインスタンス化する際には無視され、テクスチャのみが使用されます。[SkeletonGraphicCustomMaterials](/spine-unity-utility-components#SkeletonGraphicCustomMaterials) コンポーネントを使用すれば、`SkeletonGraphic` コンポーネントのマテリアルをオーバーライドすることができます。

> **重要な注意事項:**  Unityの `CanvasRenderer` の制限により、[SkeletonGraphic](#SkeletonGraphicコンポーネント)はデフォルトでテクスチャの枚数が1枚だけに制限されています。`SkeletonGraphic` コンポーネントのInspectorで `Advanced - Multiple CanvasRenderers` を有効にすると、サブメッシュごとに 子 `CanvasRenderer` `GameObject` を生成して、テクスチャの枚数上限を上げることができます。ただし、パフォーマンス上の理由から、これは可能な限り避けた方が良いでしょう。つまり、UIで使用されるスケルトンは、複数ページのアトラスではなく、単一テクスチャー(単一ページ)のアトラスとしてパックされなければなりません。
> アタッチメントを単一のアトラスページテクスチャにパックする方法については[高度な情報 - 単一テクスチャアトラスのエクスポートとSkeletonGraphic](/spine-unity-assets#高度な情報-単一テクスチャアトラスのエクスポートとSkeletonGraphic)をご覧ください。

### 正しい構成とマテリアル

`"Spine/SkeletonGraphic Tint Black"` のような特殊なシェーダーを使用したり、[CanvasGroup](#CanvasGroupアルファ)以下で `SkeletonGraphic` を使用したりするには、それに応じて頂点データを生成する必要があります。関連するパラメーターは、Inspectorの `Advanced - Vertex Data` セクションにあります。設定するのは、`Tint Black`、`CanvasGroup Compatible`、`PMA Vertex Color` の3つです。各プロパティの横には `Detect` (検出)ボタンが用意されており、これを使って自動的に正しい設定を導き出せます。また、`Detect Settings` ボタンを使えば3つのプロパティすべての設定を検出できます。

`Advanced - Vertex Data` の設定を変更したら、アクティブな設定に合わせて使用するマテリアルを更新する必要があります。
`SkeletonGraphic` では、マテリアルはテクスチャから独立しているので、同じマテリアルプロパティを使用する異なるスケルトンで共有することができます。このため、主なパラメーターとシェーダーの組み合わせに対して、特別な共有SkeletonGraphicマテリアルが用意されています。選択した `Advanced - Vertex Data` 設定に対して適切なマテリアルは、`Material` プロパティの隣にある `Detect` ボタンを使って自動的に割り当てることができます。

スケルトンが複数のブレンドモードを使用していて `Advanced - Multiple CanvasRenderers` が有効になっている場合は、`Blend Mode Materials` の隣にある `Detect` ボタンを使用することで、同様の方法で適切なブレンドモードマテリアルを自動的に割り当てることができます。

正しくない結果が表示された場合は、アトラステクスチャのインポート設定が正しくない可能性があります（ドキュメントの[こちら](/spine-unity-assets#乗算済み-vs-ストレートアルファインポート)を参照してください）。

### CanvasGroupアルファ

`Spine/SkeletonGraphic*` シェーダーを [`CanvasGroup`](https://docs.unity3d.com/ScriptReference/CanvasGroup.html) で使用すると、以下の画像のように `CanvasGroup` の `Alpha` 値 を減らすとスケルトンが明るくなってしまいます。

![](/img/spine-runtimes-guide/spine-unity/CommonError-CanvasGroupBright.png)

これは、水面下でUnityが頂点カラーのアルファ値を変更していることにより、残念ながらspine-unityランタイムの事前乗算アルファ(PMA)シェーダーではうまく再生できないためです。

> **重要な注意事項:** `Advanced - Vertex Data` セクションのパラメーターに正しい設定を自動的に割り当てるための `Detect` ボタンと、アクティブな設定に基づいて適切なマテリアルを自動的に割り当てるための `Detect Material` ボタンが用意されています。そのため、詳細な情報が必要でない限り、以下のセクションは読み飛ばしてかまいません。

#### ティントブラック無しのSkeletonGraphicの場合

`Spine/SkeletonGraphic TintBlack*` 以外の `Spine/SkeletonGraphic` シェーダーでマテリアルを使用する場合は、以下が適用されます。このようなマテリアルをアルファフェードアウトを伴う `CanvasGroup` 以下で使用する場合、そのマテリアルは `CanvasGroup Compatible` パラメーターを有効にし、SkeletonGraphicコンポーネント `PMA Vertex Colors` を無効にする必要があります:

1. 各マテリアルの `CanvasGroup Compatible` バリアントをそれぞれ `Materials/UI-PMATexture/CanvasGroup` フォルダと `Materials/UI-StraightAlphaTex/CanvasGroup` フォルダで見つけられます。  
2. この `CanvasGroup Compatible` マテリアルを、`CanvasGroup` 以下の `SkeletonGraphic` コンポーネントに割り当ててください。  
3. この `CanvasGroup` 互換マテリアルを使用する `SkeletonGraphic` コンポーネントでは、半透明部分が二重に暗くなってしまうのを避けるために、`Advanced - PMA Vertex Colors` も無効にしておく必要があります。しかしこれを設定すると、残念ながら加算スロットを通常スロットと一緒にシングルバッチレンダリングすることができなくなるため、ドローコールが増えてしまう可能性があります。  

#### SkeletonGraphic TintBlackの場合

`Spine/SkeletonGraphic TintBlack` シェーダーを使用しているマテリアルを、アルファフェードアウトを伴う `CanvasGroup` 以下で使用する場合、以下の設定が必要です:

1. `CanvasGroup` フォルダ内にある用意される `SkeletonGraphic TintBlack` マテリアルを使用してください。
2. そしてこのマテリアルを、オリジナルのマテリアルの代わりに `SkeletonGraphic` コンポーネントに割り当てます。
3. `SkeletonGraphic` コンポーネントで `Advanced - CanvasGroup Compatible` を有効にします。
4. `Advanced - PMA Vertex Colors` `SkeletonGraphic` 設定は、有効でも無効でもどちらでも動作します。`Advanced - PMA Vertex Colors` が有効であれば単一のドローコールで加算スロットをレンダリングできる利点を得られますので、一般的にはそちらが推奨されます。  

### 境界と正しい表示

`SkeletonGraphic` の表示状態はRectTransformの境界によって決定されます。スケルトンが `Canvas` GameObjectの子としてドラッグ＆ドロップでインスタンス化された場合はRectTransformの境界は自動的に初期ポーズにマッチします。また、`Match RectTransform with Mesh` ボタンをクリックすることで、RectTransformを現在のポーズの寸法に手動で合わせることもできます。RectTransformの境界がメッシュよりも小さくならないようにすることが重要です。そうしないと、例えば `RectMask2D` はメッシュの一部がまだ内側にあってレンダリングされるべきであるにもかかわらずRectTransformが外に出た時点でスケルトンの描画を省略してしまいます。現在のRectTransformの境界は、5つのトランスフォームモードの[RectTransformツール](https://docs.unity3d.com/Manual/PositioningGameObjects.html)がアクティブになっているときにSceneビューに表示されます。

### プロパティ

`SkeletonGraphic` は [SkeletonRendererコンポーネント](#SkeletonRendererコンポーネント)と同様のプロパティを提供しているので、詳しくは[SkeletonRendererセクション](#SkeletonRendererコンポーネント)を参照してください。  

![](/img/spine-runtimes-guide/spine-unity/skeleton-graphic-component-43.png)

`SkeletonGraphic` のInspectorは、以下の追加プロパティを公開しています :
* *Material - Detect* ボタン ：　`Advanced - Vertex Data` の設定に従って、適切な `"Spine/SkeletonGraphic*"` マテリアルを割り当てます。後述の `Advanced` セクションの *Detect Material* パラメータと同様です。
* *Freeze* ：　`true`に設定すると、`SkeletonGraphic`はアップデートされなくなります。

* *Layout Scale Mode* ：　`SkeletonGraphic` は、`RectTransform` の境界に基づいた自動均一スケーリングに対応しています。デフォルトは `None` で、以前の動作を維持します。自動スケーリングは、このパラメーターを `Width Controls Height`、`Height Controls Width`、`Fit In Parent` または `Envelope Parent` (それぞれの詳細は[こちら](https://docs.unity3d.com/Packages/com.unity.ugui@1.0/manual/script-AspectRatioFitter.html)を参照）のいずれかに設定することで有効にすることができます。参照レイアウト境界を変更するには、 `Edit Layout Bounds` トグルボタンを押して編集モードに入り、スケルトンの境界を調整することができます。スケルトンは、参照レイアウト境界をオブジェクトの `RectTransform` に合わせて、適宜スケーリングされます。

* *Edit Layout Bounds* ：　上記の `Layout Scale Mode` で使用される参照レイアウト境界を変更するには、このトグルボタンを押して編集モードにします。その後、手動で境界を調整するか、 `Match RectTransform with Mesh` を押して、現在のポーズに合わせることができます。調整が完了したら、 `Edit Layout Bounds` トグルボタンをもう一度押して、編集モードを終了します。

* *Match RectTransform with Mesh* ：　`Match` ボタンをクリックすると `SkeletonGraphic` のRectTransformを現在のポーズの寸法に合わせることができます。RectTransformの境界がメッシュよりも小さくならないようにすることが重要です。そうしないと、例えば `RectMask2D` は、メッシュの一部がまだマスクの内側にあってレンダリングされるべきであったとしても、RectTransformが外に出た時点でスケルトンの描画を省略してしまいます。`Layout Scale Mode` が `None` に設定されているか、`Edit Layout Bounds` トグルボタンがedit-modeに設定されていない限り、このオプションはグレーアウトされます。

![](/img/spine-runtimes-guide/spine-unity/skeleton-graphic-advanced-43.png)

* *Advanced*
	* *Update When Invisible* ：　グラフィックが親 `RectMask2D` の境界の外にあり、不可視になった時に使用されるUpdateモードです。メッシュが再び表示されるようになると、Updateモードは自動的に `UpdateMode.FullUpdate` にリセットされます。
	
		> **注意:** `Canvas` または通常の `Mask` コンポーネントだけでは、必要な可視性テストが実行されないため、必要なカリング状態を更新するためには、`RectMask2D` コンポーネントを追加してください。
	
	* *Separator Slot Names* ：　*Enable Separation*が `true` に設定されているときに、レンダリングを分割する場所を決定するスロットです。レンダリングの分割に関する全般的な情報は[SkeletonRenderSeparator](/spine-unity-utility-components#SkeletonRenderSeparator)セクションを参照してください。ただし `SkeletonGraphic` においては追加のコンポーネントは必要ありません。

	* *Enable Separation* ：　レンダリングの分割は、このInspectorセクションで直接有効にすることができ、追加のコンポーネント(`SkeletonRenderSeparator` や `SkeletonRenderer` コンポーネントの `SkeletonPartsRenderer` など)は必要ありません。有効にすると、追加の分割されたGameObjectが自動的に作成され、それに応じて `CanvasRenderer` GameObjectが再ペアリングされます。分割されたGameObjectは、必要に応じて階層内で移動させたり再配置したりして `Canvas` 内での望ましい描画順序を実現することができます。

	* *Update Part Location* ：　有効にすると、分割されたGameObjectの位置が `SkeletonGraphic` の位置に合わせて更新されます。これは、パーツを別のGameObjectに再ペアリングしたい場合に役立ちます。

	* *Multiple CanvasRenderers* ：　`true` に設定すると、`SkeletonGraphic` は1つの `CanvasRenderer` を使用せず、必要なドローコール（サブメッシュ）ごとに、必要な数の　子`CanvasRenderer` GameObjectを自動的に作成します。これにより、[単一テクスチャの制限](/spine-unity-assets#高度な情報-単一テクスチャアトラスのエクスポートとSkeletonGraphic)を緩和することができますが、パフォーマンスのオーバーヘッド（処理負荷）が発生します。
		* *Blend Mode Materials* ：　スロットのブレンドモードごとに異なる `SkeletonGraphic` マテリアルを使用できるようにします。ただしここでは、`"Spine/SkeletonGraphic *"` または他のCanvasRenderer互換のマテリアルのみを使用してください。

		* `Assign Default` を選択すると、デフォルトのブレンドモードマテリアル `SkeletonGraphicAdditive`、`SkeletonGraphicMultiply`、`SkeletonGraphicScreen` が割り当てられます。
		> **注意:**　`SkeletonGraphic` の `Blend Mode Materials` の割り当ては [`SkeletonDataAsset`](/spine-unity-assets#Skeleton-Data) のマテリアルに依存しているため、[`SkeletonDataAsset`](/spine-unity-assets#Skeleton-Data) でブレンドモードマテリアルが適切に設定されていることを確認してください。`PMA Vertex Colors` が有効な場合、`Additive Material` は無視されます。

	* *Tint Black (!)* ：　メッシュにブラックティント頂点データを追加します。スケルトンにティントブラックカラーが設定されたスロットがある場合は有効にしてください。  
	ブラックティントは、提供されている `Spine/SkeletonGraphic Tint Black*` シェーダーのように、シェーダーが UV2 と UV3 をブラックティントカラーとして解釈する必要があります。  
	親Canvasで UV2 と UV3 データを許可するには、そのCanvasを選択し、`Additional Shader Channels` で `TexCoord1` と `TexCoord2` を有効にする必要があります。  
	
		> SkeletonDataにティントブラックが設定されているスロットがあればこのパラメーターを有効にし、そうでなければ無効にする `Detect` ボタンが用意されています。

	* *CanvasGroup Compatible* ：　SkeletonGraphic が `CanvasGroup` GameObject の下で使用されている場合は有効にしてください。マテリアルも `CanvasGroup Compatible` を有効にする必要があるので、`Detect Material` を使うか、または手動でこの設定を変更した後に適切なマテリアルを割り当ててください。  
	`SkeletonGraphic Tint Black*` シェーダーを使用していて、`Tint Black` と `PMA Vertex Color` の両方が有効になっている場合、アルファ値はプライマリ頂点カラー `color.a` ではなく `uv2.g` に保存され、`color.a` は `color.a` を変更する `CanvasGroup` を捕捉するために定数 `1.0` を保存します。  

		> 階層内でSkeletonGraphicコンポーネントが`CanvasGroup` コンポーネントの下にあるならこのパラメーターを有効にし、そうでない場合は無効にする `Detect` ボタンが用意されています。

	* *PMA Vertex Colors* *[CanvasGroup alpha](#CanvasGroup-alpha)用の追加ルール）*。頂点カラーのRGB値とアルファ値を乗算します。このパラメーターはデフォルトで有効になっており、サードパーティ製シェーダーを使用する場合や、`"SkeletonGraphic TintBlack*"` 以外のシェーダーで `CanvasGroup Compatible` を有効にする必要がある場合を除き、そのままにしておくのが正しい設定です。：  

		> `Detect` ボタンが用意されていますが、これは `Tint Black` と `CanvasGroup Compatible` が正しく設定されている必要があります。`Detect` は、サードパーティー製（つまりSpineに付属しているもの以外）のシェーダーが使用されている場合、または `CanvasGroup Compatible` が有効で `Tint Black` が無効の場合、このパラメーターを無効にします。それ以外の場合はこのパラメーターを有効にします。  
		
		具体的には以下のルールが *PMA Vertex Color* に適用されます * (これが必要なのは`Detect` がうまくいかなかった時のみです)*:		

		> このパラメーターを有効にする必要がある場合 *(デフォルト)*：
		>  * 使用する `"Spine/SkeletonGraphic*"` シェーダーで `CanvasGroup Compatible` が無効になっている場合（`Straight Alpha Texture` が有効になっている場合でも）。または
		>  * `"Spine/SkeletonGraphicTintBlack*"` シェーダーを使用している場合（`Straight Alpha Texture` が有効になっている場合でも）。または
		>  * PMAとして頂点カラーを必要とするサードパーティー製（つまりSpineに付属しているもの以外）のシェーダーを使用している場合。(そのシェーダーが、PMA加算出力ブレンドモード `Blend One OneMinusSrcAlpha` を使用している場合など。)
		> 
		> このパラメーターを無効にする必要がある場合：
		> * `"Spine/SkeletonGraphicTintBlack*"` は使用していなくて、通常の `"Spine/SkeletonGraphic*"`シェーダーで `CanvasGroup Compatible` が有効になっている場合。または
		> * 通常の頂点カラーを必要とするサードパーティー製（つまりSpineに付属しているもの以外）のシェーダーを使用している場合。(そのシェーダーが、通常出力ブレンドモード `Blend SrcAlpha OneMinusSrcAlpha` で使用している場合など。)

		有効にすると、加算スロットは通常スロットと一緒に1回のドローコールでレンダリングできます。無効にすると、加算スロットのために[`SkeletonData`](/spine-unity-assets#Skeleton-Data) の *Blend Mode Materials - Apply Additive Material* を有効にする必要があり、それによって別のドローコールが必要になってしまうため、パフォーマンスに悪影響を与える可能性があります。

	* *Detect Settings*：　`Tint Black`、`CanvasGroup Compatible`、`PMA Vertex Colors` の適切なパラメーターの検出を一度に適用します。

	* *Detect Material*：　上記の `Tint Black` と `CanvasGroup Compatible` パラメーターとアトラステクスチャのインポート設定（PMA設定なのかストレートアルファ設定なのか）に基づいて、適切な `SkeletonGraphic` マテリアルを割り当てます。正しくない結果が表示された場合は、テクスチャの設定が正しくない可能性があります（詳しくはドキュメントの [こちら](/spine-unity-assets#乗算済み-vs-ストレートアルファインポート)を参照してください）。

<h4 style="font-size: 1.429em; line-height: 1.4em; margin-bottom: .4em">Example Scene</h4>!!

基本的な使用方法については、[Spine Examples/Getting Started/6 Skeleton Graphic](/spine-unity-examples#6-SkeletonGraphic)にあるサンプルシーンで確認することができます。 
また、Separator Slotを設定したり、描画順序を変更する方法を紹介している高度なサンプルシーンは、`Spine Examples/Other Examples/SkeletonRenderSeparator` で確認できます。

## SkeletonMecanimコンポーネント

`SkeletonMecanim` コンポーネントは、UnityにおいてSpineスケルトンをアニメーション化するために使用される二つのアニメーションコンポーネントの一つであり、もう一つは[SkeletonAnimation](#SkeletonAnimationコンポーネント)コンポーネントとなります。レンダラーコンポーネントが必要であり、通常はスケルトンの管理とレンダリングを行う[SkeletonRenderer](#SkeletonRendererコンポーネント) コンポーネントと組み合わせて使用されます。

![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-component-43.png)

`SkeletonMecanim`コンポーネントは、ハイレベルな制御にはUnityのMecanimアニメーションシステムを使用し、スケルトンのポーズ設定と構築にはSpineのアニメーションシステムを使用します。
Mecanimシステムは、どのSpineアニメーションを再生すべきかを決定し、各アニメーションのトラック時間とアルファ値を決定します。その後、該当するSpineアニメーションは、コンポーネントによって[Spineスケルトンに適用されます](/spine-applying-animations#Timeline-API)。

[SkeletonAnimation](#SkeletonAnimationコンポーネント) コンポーネントと同様に、`SkeletonMecanim` はSpineスケルトンをアニメーションさせたり、アニメーションイベントに反応させたりすることが可能です。SkeletonMecanimではなく[SkeletonAnimation](#SkeletonAnimationコンポーネント)を使用する場合と同様に、アニメーションが適用された後、スケルトンが描画される前にスケルトンに変更を加えることもできます。

### 制限事項

[SkeletonAnimation](#SkeletonAnimationコンポーネント)と比較すると、以下のようないくつかの制限と追加要件があります:

1. [SkeletonAnimationコンポーネント](#SkeletonAnimationコンポーネント)とは異なり、`SkeletonMecanim` は先行するアニメーションのタイムラインの状態をスムーズにミックスアウトするためには、アニメーションの最初のフレームで追加のタイムラインキーを必要とします。詳しくは後述の[必要になる追加のキー](#必要になる追加のキー)をご覧ください。

2. [`TrackEntry.MixAttachmentThreshold`](/spine-api-reference#TrackEntry-mixAttachmentThreshold) および同様のミックスしきい値の機能は `SkeletonMecanim` では使用できません。

3. *Threaded Animation* を使用している場合、`SkeletonMecanim` は `SkeletonAnimation` よりもパフォーマンスが低下します。これはアニメーション処理全体をワーカースレッド上で実行できないためです。Mecanimコントローラーの状態を参照するいくつかの呼び出しは、メインスレッド上で実行する必要があります。そのため、並列化による性能向上が大きく制限されます。

### 必要になる追加のキー

あるアニメーションから次のアニメーションへとタイムラインの状態（ボーンの回転など）をスムーズにミックスアウトさせるために、2つ目のアニメーションでは、最初のフレームでセットアップポーズの状態の追加のキーが必要になります。そうしないと、前のアニメーションのタイムラインの状態が残ってしまうからです。これは[SkeletonAnimation](#SkeletonAnimationコンポーネント)と比較した際の `SkeletonMecanim` の欠点の一つです。

> 簡単な例: `idle` アニメーションが、先に再生されている `jump` アニメーションをスムーズにミックスアウトする必要があるとします。`jump` の終了時にボーン `bone1` と `bone2` がセットアップポーズとは異なる位置でキー設定されている場合、`jump` の状態を適切にミックスアウトするためには、`idle`アニメーションの最初のフレームに `bone1` と `bone2` のキー(セットアップポーズまたは任意のポーズ)を追加する必要があります。

`Auto Reset` パラメーターを使えばタイムラインの状態をリセットできますが、アニメーションのトランジション終了時に唐突にミックスアウトしてしまい、スムーズなトランジションを実現できません。

また、スケルトンを `.json` または `.skel.bytes` でエクスポートする際は必ず `Animation cleanup(アニメーションクリーンアップ)` を無効にしてください。そうしないとセットアップポーズと全く同じキーはエクスポートされなくなってしまいます!

### プロパティとアニメーションブレンドのコントロール

`SkeletonMecanim` コンポーネントには[SkeletonAnimationコンポーネント](#SkeletonAnimationコンポーネント)と類似したパラメーターが用意されているので、詳しくは[SkeletonAnimationセクション](#SkeletonAnimationコンポーネント)を参照してください。

![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-component-43.png)

`SkeletonMecanim` のInspectorは以下の追加パラメーターを公開しています : 
* *Mecanim Translator*
	* *Auto Reset* ：　`true` に設定すると、アニメーションが終了したときに、アニメーションのキーが設定されたアイテムに応じて、スケルトンの状態がセットアップポーズにミックスアウトされます。これは、アニメーションがアタッチメントの表示状態を変更した場合に特に重要になることがあります。ミックスアウトされると、アタッチメントの表示状態はセットアップポーズの状態に戻りますが、そうでなければ、現在のアタッチメントの状態は別のアニメーションがそれぞれのアタッチメントのタイムラインにキーを設定するまで保持されます。

	* *Custom MixMode* ：　無効にすると、レイヤーのブレンドモードに応じて、推奨される `MixMode` が使用されます。有効にすると、以下のような `Mix Modes` セクションが表示され、各Mecanimレイヤーの `MixMode` を指定することができます。

	* *Mix Modes* ：　上記の `Custom MixMode` パラメーターが有効な場合に表示されます。このパラメーターは、連続したアニメーション間、およびレイヤー間のアニメーションのミックスモードを決定します。
		* Mix Next  *（`Base Layer` と `Override` レイヤーで推奨されます）*  
	 		前のトラックを適用した後、Mecanimのトランジションウェイトを使って次のトラックを上からミックスします。
		* Always Mix  *（`Additive` レイヤーで推奨されます）*  
			前のトラックをフェードアウトし(`Auto Reset` が有効な場合、セットアップポーズになる可能性があります)、Mecanimのトランジションウェイトを使用して次のトラックをトップにミックスします。Base Layerに使用すると、意図しないアニメーションのディッピング効果が発生する場合がありますのでご注意ください。
		* Hard  *（旧名称：`Spine Style`）*
			次のトラックをすぐに適用します。
		* Match *(バージョン4.2の新機能で、任意のレイヤ０上でブレンドツリーノードを使用する場合に推奨されます。)*
			指定されたMecanimクリップのウェイトに最適に一致するよう、Spineアニメーションのウェイトを計算します。

* *Scene Preview* ：　Animationウィンドウで選択されたアニメーションクリップをプレビューします。InspectorでSkeletonMecanimコンポーネントを表示したまま、Animationウィンドウを開き、アニメーションクリップを選択してください。その後、Animationウィンドウでタイムラインをスクロールして確認できます。

#### **`Auto Reset`とレイヤーの`Mix Mode`パラメーターの結果**

トランジションがアクティブになる際、`現在のステートの最後のフレーム` と `セットアップポーズ`、`前のクリップのポーズ` と `新しいクリップのポーズ` の4つのポーズがあり、これらは次のように組み合わされます :
1. まず `現在のステートの最後のフレーム` *(またはSkeletonMecanimのupdate前のこのフレームの他の修正)*で開始します。
2. `セットアップポーズ` を適用します :
	* `Auto Reset` が有効な場合、`セットアップポーズ` が `現在のステートの最後のフレーム` に置き換わります。
	* `Auto Reset` が無効な場合、`セットアップポーズ` はミックスに含まれません。
3. `前のクリップのポーズ` を適用します :
	* モードが `Always Mix` に設定されている場合は、`前のクリップのポーズ` が現在の状態とミックスされます (`Auto Reset` が有効な場合は `セットアップポーズ` とミックスされます）。
	* `Hard` または `Mix Next` に設定されている場合は、`前のクリップのポーズ` がフルウェイトで適用され、現在のステートよりも優先されます(つまり `セットアップポーズ` よりも優先されます)。
4. `新しいクリップのポーズ` を適用します :
	* モードが `Always Mix` または `Mix Next` に設定されている場合、`新しいクリップのポーズ`は現在のステートとミックスされます。つまり、`Auto Reset` を有効にしている場合の `Always Mix` は、`セットアップポーズ`、`前のクリップのポーズ`、`新しいクリップのポーズ` が混合されます。
	* モードが `Hard` に設定されている場合、`新しいクリップのポーズ` はフルウェイトで適用され、以前に適用されたすべてのポーズよりも優先されます。

下の表は、前のクリップ `P` と新しいクリップ `N` の両方が同じタイムラインの値（例えば同じボーンの回転)を変更する場合を表しています。`S` は、`Auto Reset` が有効な場合はセットアップポーズを、無効な場合は現在のステート(例：前フレームのステート）を表します。トランジションウェイト(トランジション開始時に0、トランジション終了時に1)は、変数 `w` で表されます。各レイヤーのブレンドモードにおけるデフォルト（推奨）のミックスモードは、太字でハイライトされています。

<table>
	<thead>
		<tr>
			<th></th>
			<th>Always Mix</th>
			<th>Mix Next</th>
			<th>Hard</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<th align="right">Base Layer</th>
			<td align="center">lerp(lerp(S, P, 1-w), N, w)</td>
			<td align="center"><b>lerp(P, N, w)</b></td>
			<td align="center">N</td>
		</tr>
		<tr>
			<th align="right">Override</th>
			<td align="center" colspan="1">lerp(<br>lerp(lower_layers_result,<br>P, (1-w) * layer_weight),<br>N, w * layer_weight)</td>
			<td align="center" colspan="1"><b>lerp(<br>lerp(lower_layers_result,<br>P, layer_weight),<br>N, w * layer_weight)</b></td>
			<td align="center" colspan="1">lerp(lower_layers_result,<br>N,<br>layer_weight)</td>
		</tr>
		<tr>
			<th align="right">Additive</th>
			<td align="center" colspan="1"><b>lower_layers_result +<br>layer_weight * lerp(P, N, w))<b></td>
			<td align="center" colspan="1">counts as Always Mix</td>
			<td align="center" colspan="1">lower_layers_result +<br>layer_weight * N</td>
		</tr>
	</tbody>
</table>

<table>
	<thead>
		<tr>
			<th>省略形</th>
			<th>意味</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td align="center">S</td>
			<td align="left"><b>S</b>etup pose(セットアップポーズ)</td>
		</tr>
		<tr>
			<td align="center">P</td>
			<td align="left"><b>P</b>revious clip pose(前のクリップのポーズ)</td>
		</tr>
		<tr>
			<td align="center">N</td>
			<td align="left"><b>N</b>ew clip pose(新しいクリップのポーズ)</td>
		</tr>
		<tr>
			<td align="center">w</td>
			<td align="left">Transition <b>w</b>eight(トランジションウェイト)</td>
		</tr>
		<tr>
			<td align="center">lerp(a, b, weight)</td>
			<td align="left"><b>L</b>inear int<b>erp</b>olation from a to b by weight (aからbへのウェイトによるリニア補間)</td>
		</tr>
	</tbody>
</table>

### ControllerとAnimator

`SkeletonMecanim` コンポーネントは、UnityのMecanimと同様に `Animator` コンポーネントで割り当てられたControllerアセットを使用します。Controllerアセットはスケルトンを[ドラッグ&ドロップ](#スケルトンをシーンに追加する)で` SkeletonMecanim` としてインスタンス化する際に自動的に生成され、割り当てられます。

![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-animator.png)

> **補足:**　`Apply Root Motion` を有効にすると、[SkeletonMecanimRootMotion](/spine-unity-utility-components#SkeletonMecanimRootMotion)コンポーネントが `SkeletonMecanim` GameObjectに自動的に追加されます。

Controllerのアニメーションステートマシンにアニメーションを追加するには、SpineアニメーションをAnimatorパネルにドラッグ＆ドロップします。アニメーションはControllerアセットの下にあります。

![](/img/spine-runtimes-guide/spine-unity/skeleton-mecanim-anim.png)

[SkeletonDataAsset](/spine-unity-assets#Skeleton-Data-Asset)で設定された[Mix duration](/spine-unity-assets#Mix-Settings)値は、`SkeletonMecanim` では無視されます。代わりにAnimatorパネルで設定したMecanimのトランジションタイムが使用されます。

### SkeletonMecanimイベント

`SkeletonMecanim` を使用する場合、イベントは各 `AnimationClip` に格納され、他のUnityのアニメーションイベントと同様に発生します。例えば、Spine内でイベント名を `"Footstep"` と命名した場合、`SkeletonMecanim` のGameObjectに `MonoBehaviour` スクリプトを用意し、`Footstep()` というメソッドを用意して処理する必要があります。Spine内でフォルダを使用している場合、メソッド名はフォルダ名とアニメーション名を連結したものになります。例えば、先ほどのイベントが `Foldername` というフォルダに入っている場合、`FoldernameFootstep()` となります。

```csharp
public class YourComponentReceivingEvents : MonoBehaviour {
	// フォルダの外に置かれてる場合にイベント"Footstep"をキャプチャする
	void Footstep() {
		Debug.Log("Footstep event received");
	}

	// "Foldername"というフォルダの中に置かれている場合にイベント"Footstep"をキャプチャする
	void FoldernameFootstep () {
		Debug.Log("Footstep (in folder Foldername) received");
	}
}
```

Unity Mecanimのイベントの詳細については、[アニメーションイベントに関するUnityのドキュメント](https://docs.unity3d.com/Manual/script-AnimationWindowEvent.html)を参照してください。

[次: ユーティリティコンポーネント](/spine-unity-utility-components)
[前: アセット](/spine-unity-assets)