Unityでドット絵アニメーションをコードで編集して撮影する


前提としてUnityの初学者である私が、ドット絵ゲームを作るうえで調べたことを共有する記事です。
熟練者の技術ではないことにご注意ください。ざっくりとした説明になりますので、詳細はキーワードからググってください。

この記事は、このアニメーションをUnityで作成したときのポイントになった点をまとめています。
![f2000_1.gif](https://qiita-image-store.s3.amazonaws.com/0/254824/6cf39a00-a44d-858d-c6ea-5ad158c66465.gif)

ソースもまた置いておきますね。（アニメーションをさせる目的で作ったものなので強引なつくりをしています。）
[[GtiHub　akari2100]](https://github.com/pixelflag/akari2100)

そして、前回記事の[[ドット絵ゲームをunityで作るときに押さえておきたいポイント]](https://qiita.com/pixelflag/items/ad817bdd64931e084a46)での、アニメーション制御の訂正記事です。
コードで制御したほうが楽かもと書いたのですが、Animatorでも制御が楽そうな感じになってきたので、まとめなおしています。

# Animatorを使ったコード上でのAnimation制御

animatorでも簡単な方法が最初からありました。このような表記で簡単に切り替わります。

```C#
animator.Play("Base Layer." + animationName);
```
Animator内は遷移でつなぐ必要なし。

![akari001.png](https://qiita-image-store.s3.amazonaws.com/0/254824/b2b14977-8654-931f-5c25-ddb09953ed0b.png)
Animatorの中にAnimationをほうりこんでおくだけで認識するみたいです。Animation Contorollerも必要なし。

終了を待たず、実行したタイミングで、パッと切り替わります。
AnimatorのGUI上で遷移を繋いだものとの併用も可能なので、遷移をつないでいく通常のAnimatorの使い方と併用すると効率が良さそうです。

これで、animationを切り替えることが出来ました。次はアニメーションの切り替えタイミングの制御です。

# イベント制御
Animation内にEventを配置することができます。
イベントで終了を設定することで終了の処理を行います。（これ以外の方法がありそうですが、見つかりませんでした。）
![akari002.png](https://qiita-image-store.s3.amazonaws.com/0/254824/223a0d6c-9200-a514-f6af-cb0369cf982b.png)
Animationの最後に、アニメーションの終わりをつげるEventを設定します。

![akari003.png](https://qiita-image-store.s3.amazonaws.com/0/254824/d106c38e-92d7-4b0b-33cd-81fcf50c871a.png)
AnimationEventに、実行するFunctionを登録できるので、これでアニメーションの終わりを取得します。
Animatorなどの、アニメーションがn回終わったら、次のアニメーションに移行するという制御がこれでできます。

### 

# アニメーションの相対的な移動
Animationでは初期設定では、座標移動などはアニメーション終了時にリセットされてしまいます。
移動をそのまま反映させたいときは、以下の設定が必要になります。
![akari004.png](https://qiita-image-store.s3.amazonaws.com/0/254824/b318796d-3682-4e0d-0a00-3f7e0bd5ca6b.png)
Animationの「Generate Root Motion Curves」。

![akari005.png](https://qiita-image-store.s3.amazonaws.com/0/254824/647245b9-9ea7-867a-e1c7-4c2cc480203e.png)
Animatorの「Apply Root Motion」をON。
これで、Animationのタイムラインで設定した、座標移動はリセットされずに、座標が更新されたままになります。


# 同じアニメーションを使い、別グラフィックに差し替える
ドット絵アニメの場合、Animationを流用して同じアニメーション制御で、色変えなど、絵だけ差し替えたいケースが多くあります。
通常であれば、バリエーション分のAnimationを作ることになってしまいます。
これはランタイムで、テクスチャを無理やり差し替える方法で解決できました。

こんな色違いキャラなど。（パレットチェンジではなく、普通に別画像になっています）
![f2000_1.gif](https://qiita-image-store.s3.amazonaws.com/0/254824/6cf39a00-a44d-858d-c6ea-5ad158c66465.gif)


```C#
    public Texture replacetexture;

    private SpriteRenderer spriteRenderer;
    private static int idMainTex = Shader.PropertyToID("_MainTex");
    private MaterialPropertyBlock block;

    void Start()
    {
        block = new MaterialPropertyBlock();
        spriteRenderer = GetComponent<SpriteRenderer>();
        spriteRenderer.GetPropertyBlock(block);
    }

    void Update()
    {
        block.SetTexture(idMainTex, replacetexture);
        spriteRenderer.SetPropertyBlock(block);
    }
```

textureを強引に差し替えています。アニメーションなどで複数のTextureに分けている場合、現在のアニメーションを調べて、差し替えるTextureを変えます。高頻度で実行するのであまりスマートではないです。それにTextureをまとめることができないので、描画効率も問題になりそうです。
Textureは、SpriteのTexture座標をそのまま使うので、差し替えるTextureは同じ座標に絵が配置されていなければならない制限があります。

# アニメーションの撮影
今回、Unityでアニメーションをつけ、色変えのキャラクターを作り、最終的にGIFアニメにしました。
Unity上で、そのアニメの連番画像の撮影を行っています。

```C#
public class Root : MonoBehaviour
{
    string folder = "Screenshot";

    void Start ()
    {
        Time.captureFramerate = 25;
        System.IO.Directory.CreateDirectory(folder);
    }

    void Update()
    {
        string fileName = string.Format("{0}/{1:D04} akari.png", folder, Time.frameCount);
        ScreenCapture.CaptureScreenshot(fileName);
    }
}
```

Screenshotフォルダをつくり、そこに連番png画像を保存します。
毎フレームの撮影はなかなか重い処理です。そんなときは、Time.captureFramerateで調整しフレームの実行間隔を調整します。（法則性がよくわからず、いい感じなるようにとにかくいじり倒しました。）

# おわり
Unityは、キャラのパラメータを設定して複数キャラをそれぞれの動きを制御できるので、一般的なアニメーション編集ツールなどとはまた違った動きの管理が出来て面白いです。（最初に動くまでのハードルが高いのが問題ですが。）
Unityはまだまだ開拓中です。また良い方法を見つけたら修正していきます。