【2021年】Unity 2D Animationの使い方

本記事はQualiArts Advent Calendar 2021の23日目の記事となります

https://qiita.com/advent-calendar/2021/qualiarts

# はじめに
個人的にUnityでの演出周りに興味があり、今回記事にした「2DAnimation」 について過去にアウトプットしてました。（このQittaではないですが）
今回アドベントカレンダーを書く機会をいただくにあたり、現在「2DAnimation」がどうなっているのか気になっていましたので調べ直してみました。
Unityにはとてもたくさんの機能が随時アップデートされているのですが、自分肌感、「2DAnimation」に関しては余り盛り上がっているとは言えない気がしますが、それは気にしません。

# Unity 2DAnimationとは
Unityで2DAnimationを実装をする場合には、これまではSpineやLive2Dなどの外部のツールを使っていました。
2DAnimationはUnity公式ツールとしてこれらの外部ツールのようなことが実装できます。

Unity公式で2DAnimationについて詳しくまとめられていますので、興味のある方はぜひこちらを見てみてください。

https://unity.com/ja/features/2danimation

### 2D PSD Importer
2DAnimationでアニメーションを作成するときに便利なツールです。
PSB(PSDではない）のデータをインポートした時に自動的に2DAnimationで編集できる状態に設定をしてくれます。

https://docs.unity3d.com/Packages/com.unity.2d.psdimporter@2.1/manual/index.html

# 環境
今回記事を書いた時点での開発環境は次になります。
- Unity2021.2.5f1
- 2DAnimation 7.02
- 2D PSD Importer 2.1.10

# 導入方法
PackgeManagerから「2DAnimation」をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/d5b51328-abb1-2b6b-36db-d69532d864a1.png)

また、同じようにして「2DPSDImporter」をインストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/ce34c1a6-b0b5-7958-7436-c0ae1197fa56.png)

#画像データの作成
2DAnimationで利用する画像を「2D PSD Importe」を使って読み込みます。
とはいっても、PSB（ビックドキュメント形式）ファイルをプロジェクトへ追加するだけでです。

## 画像用意
Photoshopで画像データを作成し、ビックドキュメント形式で保存をします。
注意していただきたいのが、**ビックドキュメント形式**で保存しないといけないことです。
<img width="300" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/509c155e-be6c-d54b-e5e5-f4c49763fc4a.png">

### レイヤー分け
2D PSD Importerはレイヤーごとに画像に書き出してくれます。
Photoshopで次のようにレイヤー分けをしておけば
<img width="300" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/16ea3c0a-d3c6-7bba-86ae-d08bc3ec1629.png">

「2D PSD Importer」がUnity上で良い感じプレハブを分けてくれます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/8759b8aa-cf12-3cb1-cae4-c13fa0ab76a3.png)


「2D PSD Importer」についてはUnityのこちらの記事で詳しく説明されています。
興味のある方はぜひこちらを見てみてください

https://blog.unity.com/ja/technology/how-to-speed-up-2d-art-workflows-with-2d-psd-importer

# アニメーションの作成前準備
　            
アニメーションの作成の前に次の3つの工程が必要です
- Bone作成・設定
- Geometry作成・設定
- Weight設定

## SpriteEditor
こちらの3つの工程はSpriteEditorで行います。
**Window => 2D => SpriteEditor** で開きます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/8db55e35-1536-ba9b-8c1b-5b24caae924b.png)

対象となる画像データを選択し、Skinning Editorを開きます。
<img width="300" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/6d3fe9f6-1919-4a4b-a602-aa79f181ed31.png">

## 保存
Skinning Editorで何かしら編集を行った後には**「Apply」**を押す必要があります。
これをしないと編集をしたデータが反映されませんので注意をしてください。

## Visibility
「Visibility」では、SpriteやBoneの階層の調整や表示非表示などの調整ができます。
<img width="300" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/1ae4ec03-2f52-81fe-e9a6-aa52fa0c5c73.png">


#Bone作成・編集
アニメーション時に動かすBoneの作成を行います。
左の「Bones」のパネルを使います。

- **Edit Bone** : 作成済みのBoneを調節します
- **Create Bone** : 新規Bone作成する
- **Split Bone** : Boneを2つに分ける

<img width="400" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/bf2c25fe-27ee-72e3-b60e-37049b5c3211.png">

## Boneの削除
削除は`Command + BackSpace`で行えます（Mac)

#Geometry作成・編集
画像に頂点や線を追加してGeometryを作成します。
Weightsの編集時、このGeometryを使います。

- Auto Geometry : 自動生成
- Edit Geometry : Geometryの編集
- Create Vertex : 頂点の作成
- Create Edge : 線の作成
- Split Edge : 線の分割

<img width="400" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/07d04113-3dc2-dbef-30d2-a598bb43512f.png">

### Geometryの構成
Geometryは**頂点**と**線**でできています。
頂点で各BoneのWeightを設定できるので、頂点数が多くなるほど細かな動きを実現できます。


# Weights
Boneを動かしたときのGeometoryの影響度(Weight)を設定します。

- Auto Weights : 自動設定
- Weight slider : スライダーを使って設定
- weight Brush : ブラシを使って設定
- Bone Influence
- Sprite Influence

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/49dc6491-d5d0-8712-1ef8-98090faa454a.png)

Weightsの設定に関しては実際にBoneを動かして調整を行います。

### Weights Slider
頂点まわた線を選択した状態で、Weightの調整を行います。
「Vertex Weight」で対象のBoneを選んで調整します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/8ae0dd52-da0b-e88d-a66f-23971f15cd3f.png)

### Weights Braush
ブラシを使って対象ボーンのWeightの調整を行います。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/ccb14d59-d6df-d610-0d6f-fcb2c9f88efd.png)

主に調整する項目は次の3つです。
- Size : ブラシの大きさ
- Harness : ブラシを動かすことによって適用されるWeightの量。大きほどすぐ適用される。
- Step : 対象のボーンへの影響度合い、数字が少ないほどすぐに適用される

### Bone Influence
対象の画像(Sprite)に影響しているBoneを表示します。
「+」「-」で調整ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/c9535087-a676-ffd9-b36b-da182a24f534.png)

### Sprite Influence
対象のBoneに影響している画像（Sprite)を表示します。
「+」「-」で調整ができます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/d3b0f910-c06c-72c3-babf-27258e2cafc0.png)

# Rig
「Rig」に関しては前回自分が調べた際にはなかった項目の気がします。
BoneとMeshのデータをコピー・アンド・ペーストできます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/17e40574-8853-ef1b-f907-faa8fe159c46.png)

対象のMeshを選択した状態で「Copy Rig」のボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/2524b9cf-e43a-3a28-63a8-1e29359d1d00.png)

ペースト対象のPSBデータを開いて、「Paste Rig」を押します。
ボタンを押しただけではペースされないので、次のUI画面の「Paste」ボタンを押します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/c6ce1a2c-6e7b-3801-6f6e-7a97a82e5145.png)

何をCopyするかを選択できます。
また向きを反転してPasteすることもできます。

### Rigの利用想定
左右対称の画像データの場合、片側だけBoneやWeightの設定をすれば、後はこの機能を使えば作業時間が半分に済みそうです。

# IK
この項ではIKを実装するための手順を紹介します。

https://school.dhw.co.jp/course/3dcg/contents/w_ik.html

### IK Manager 2D
GameObjectのコンポーネントに「IK Manager 2D」をアタッチします。
Inspectorに次のように表示されます。
<img width="400" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/d8f66b79-c284-2b5a-6cf4-adaa61778d30.png">

IK Solversが空だと思うので、「+」を押して追加します。
IKの種類が3つあるのですが、今回はLimbを選んでみます。

- Chain(CCD)
- Chain(FABRIK)
- Limb

#### Limb
Limbは腕や足などの関節に最適化されたIKです。
>This is a standard two bone Solver that is ideal for posing joints such as arms and legs. This Solver’s chain length is fixed to three bones - starting from the Effector bone/Transform and including up to two additional bones in its chain.

「IK Manager 2D」をアタッチしたGameObject配下にNewLimbSolver2DというGameObjectが作成されていると思います。
<img width="500" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/f11d5a8e-af66-9521-c1b6-61bc3d747757.png">

EffectorでIKの対象となるボーンを選択します。
選択が終われば「Create Target」のボタンを押すとIKのターゲットとなるGameObjectが作成されます。
(階層的には次のような感じです）
<img width="300" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/e4bc343e-7d8a-6711-17e1-0ecfad69aed9.png">

アニメーションを作成するときにはボーンではなくこのターゲットを動かします。

#### Chain
Limb以外にはChainが２種類作成することができます。
ともに計算のアルゴリズムが違うので、実際に使ってみて動きを確かめてみるのもよいかもしれません。

https://docs.unity3d.com/Packages/com.unity.2d.ik@1.1/manual/index.html

# Animation
ボーンやWeightの設定が終われば実際のアニメーションを組んでいきます。
こちらはUnity標準のAnimatorを使って実装していきます。

# Sprite Swapping
再生中に特定の画像（Sprite)を変更できるようになります。
SpriteLibraryAssetで切り替えるための画像データを調整します。

## SpriteLibraryAsset
Category名を指定し、Entry内に必要な画像を準備します。
今回の画像の例では色違いのリボンを登録しています。
<img width="450" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/4507bce4-28d7-eae5-139a-5f4d2418642d.png">

SpriteLibraryAssetにCategoryは複数登録できます。

### 必要なコンポーネント
画像を変更するために必要となるコンポーネントはいかになります。

- SpriteRender
- SpriteLibrary
- SpriteResolver

SpriteRenderは特に触る必要はないです。
#### SpriteLibrary
SpriteLibraryAssetが設定できます。
Inspector上でも編集ができます。
<img width="450" alt="gasou" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/b83fa401-3c1d-85ee-7c05-b5b01ace62b8.png">

#### SpriteResolver
表示するCategoryとLabelを選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/61216/e79f900e-137b-582e-988b-b637028581e5.png)

SpriteResolverはScriptを使って変更が可能です。

```C#
_spriteResolver.SetCategoryAndLabel("Ribbon", "green");
```

SpriteResolverのその他関数についてはこちらから。

https://docs.unity3d.com/Packages/com.unity.2d.animation@3.0/api/UnityEngine.Experimental.U2D.Animation.SpriteResolver.html

# 最後に
「Sprite Swapping」は過去に調べたときにはなかった機能でしたので今回調べるにあたり新しい発見があって良かったと思います。
この機能はAnimationをするしないに関わらず何かしらで使えそうな気がしましたので、もう少し詳細を見てみようと考えています。