[Unity] Unicessingで作った演出をバナー等の背景に使うといい感じになる

この記事は [Unity Advent Calendar 2018](https://qiita.com/advent-calendar/2018/unity) 14日目の記事です。
前の記事は @adarapata さんによる [「Zenject Signals」 ](http://adarapata.hatenablog.com/entry/2018/12/13/041721) でした。
Zenjectを導入するとPub/Subの仕組みが付いてくるの、お得感がありますね！

# 実行環境
* Unity 2018.2.16f
* Unicessing 0.21.1

# 概要
勉強会を主催したりお手伝いする際にバナーの作成をやらせていただいております。
そのバナーの作成にUnityを使うと、面白い表現が出来ると最近感じています。
例えば、以前 [[Unity] ParticleSystemでMeshを描画してバナー等の背景に使うといい感じになる](https://qiita.com/lycoris102/items/6bf631b35d2769b2d475) という記事を書きました。
上記では `ParticleSystem` を利用して `Mesh GPU Instancing を有効にする` ことで多量のMeshを生成し、それをバナーの背景に利用するということをしました。

<blockquote class="twitter-tweet" data-lang="ja"><p lang="und" dir="ltr"><a href="https://t.co/6sAxyoNbxe">pic.twitter.com/6sAxyoNbxe</a></p>&mdash; 青木とと(ˊᗜˋ*){Unity課金・広告勉強会12/5(水) (@lycoris102) <a href="https://twitter.com/lycoris102/status/1041301310702706688?ref_src=twsrc%5Etfw">2018年9月16日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

今回は Unicessing というアセットを使用して以下のようなバナーを作った事例を紹介します。
立ち位置的には **「Unicessing 入門/触ってみた」** というものになります。
(Unity Network完全に理解した勉強会は12/11に開催され、近日資料も [Unity Learning Materials](https://learning.unity3d.jp/) にて公開予定です)

<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">(今回もひっそりバナー作成しました) <a href="https://t.co/5h27XJ1CKD">pic.twitter.com/5h27XJ1CKD</a></p>&mdash; 青木とと(ˊᗜˋ*){Unity課金・広告勉強会12/5(水) (@lycoris102) <a href="https://twitter.com/lycoris102/status/1059442155255517187?ref_src=twsrc%5Etfw">2018年11月5日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

# Proccesing について
[Processing](https://processing.org/) はJavaを元にしたデジタルアート/ビジュアルデザインの制作に特化したプログラミング言語および統合開発環境です。オープンソースで提供されています。Processing には [関数群](https://processing.org/reference/) が用意されており、これらの組み合わせにより図形を描画したり入力を受け取ったりすることとなります。2001年に開発がスタートされた言語であり、既に多くの人の手によってチュートリアル/サンプル/書籍が制作されています。

[Processing とは - Processing 学習ノート](http://www.d-improvement.jp/learning/processing/class/about-processing.html)
[Processing基礎最速入門 - catch.jp-wiki](https://www.catch.jp/wiki/?Processing%B4%F0%C1%C3%BA%C7%C2%AE%C6%FE%CC%E7)

# Unicessing について
![unicessing1.png](https://qiita-image-store.s3.amazonaws.com/0/102664/3971b289-3f43-9006-c018-01d9aeff9782.png)

[Unicessing - Asset Store](https://assetstore.unity.com/packages/tools/integration/unicessing-75728)
[Unicessing: 総合概要](http://dev.eyln.com/unicessing/doc/jp/)
[Unityで手軽にProcessingっぽく図形を描いて遊べるアセット Unicessing を作ったの巻 - 遊んで航海記](http://eyln.hatenablog.com/entry/2016/12/04/231439)

Unicessing は Processing のような記法で図形描画出来るアセットで、[@n_ryota](https://twitter.com/n_ryota) さんが2016年にリリースしました。Unity上で Processing を扱える様にしたことで 「xRを含むマルチプラットフォームへの手頃な対応」「ポストエフェクト等の画面効果の適応が容易」という恩恵を得ることが出来ます。

# Hello World
## AssetStoreから購入/インポート
Unityで新規プロジェクトを立ち上げて、AssetStoreを立ち上げ、Unicessingで検索/購入。

![unicessing2.png](https://qiita-image-store.s3.amazonaws.com/0/102664/188c3a1b-224e-e936-de8b-3ffe232f0aa8.png)

インポートを実行するとUnityのバージョンによっては `API Update Required` が出ますが `I Made abackup, Go Ahead!` を選択し、Unityの最新のAPIに追従させて問題ありません。

<img width="233" alt="unicessing3.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/ada78967-aabc-320a-175c-bf015741a153.png">

## UGraphicsを継承したスクリプトの作成
無事にインポート出来たら、次はスクリプトを記載します。新しく C# Scriptを作成し、例えば以下のように記載します。

```csharp:UnicessingSample.cs
using Unicessing;
using UnityEngine;

public class UnicessingSample : UGraphics
{
    private int lineCount = 10;
    private Vector2[] positions;

    protected override void Setup()
    {
        positions = new Vector2[lineCount];
        for (int i = 0; i < this.lineCount; i++)
        {
            positions[i] = new Vector2(Random.Range(-10f, 10f), Random.Range(-10f, 10f));
        }
    }

    protected override void Draw()
    {
        for (int i = 0; i < this.lineCount; i++)
        {
            this.drawLine(positions[i]);
        }
    }

    private void drawLine(Vector2 position)
    {
        stroke(255, 255, 255); // Color
        line(position.x, position.y, mouseX, mouseY); // Draw Line
    }
}
```

`Setup` には初期化時に実行したい挙動を定義します。`Draw` には描画したい内容を定義します。下記のサンプルでは `mouse` 値を参照し線を動かしていますが、内部的に `Update`で毎フレーム毎に描画を消しつつ描画し直しているような挙動になっています (ただし `noloop()` 関数を実行することで描画ループを止めることも可能です)

スクリプトを記載したら、任意のGameObjectにアタッチします。

<img width="600" alt="unicessing4.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/7088c7ac-0884-b420-21db-6c43008a8a72.png">

この状態で実行すると、線が `lineCount` の数だけランダムな座標とマウス座標を結ぶように描画されます。

![unicessing1.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/c75dd001-7b82-6c29-b7e7-dbe5c31969b8.gif)

# OpenProcessing からコードを移行してみる
上記のようなコードでシンプルな座標を描画/アニメーション出来ることは分かりました。
しかし、知識の引き出しがない状態だと、何をどうしたら良い表現が作れるのか分かりません。
なので、既に作られている Processing のコードをベースに学習してみることにします。

![uniccessing5.png](https://qiita-image-store.s3.amazonaws.com/0/102664/d0821c1d-0de3-935f-60be-c1955c980bb9.png)

[OpenProcessing](https://www.openprocessing.org/) は Processing で作られたジェネレーティブアートやゲームの投稿サイトです。
試しに Processing で作られた [パーティクルの一覧](https://www.openprocessing.org/browse/?q=particle&time=anytime&type=tags#) を見てみると多くの作品が投稿されていることが分かります。

![unicessing2.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/0290f3d3-3301-c423-0edb-a20a3a00be9c.gif)

https://www.openprocessing.org/sketch/460479
今回はこのパーリンノイズを用いたTerrainの作品を見てみましょう。
詳細ページからサンプルとコードを見ることが出来ます。
(こちらのコード自体の理解は [こちら](https://www.youtube.com/watch?v=IKB1hWWedMk) の動画を参照)

このコードをUnityに移植してみます。
フィールド値 / Setup関数 / Draw関数のそれぞれを先ほど作ったScriptに持って行きます。

<img width="1079" alt="unicessing5.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/2f362dcf-553e-7365-ec1c-f29e5e4c5ba9.png">

いくつか例外が出ていますが、クリティカルなものはそこまでありません。

<img width="306" alt="unicessing6.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/9cc14469-655d-f026-ff21-16f4c168a75b.png">

<img width="306" alt="unicessing7.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/9f99d6ef-e770-610b-a444-fde6c4765080.png">

二次元配列の定義を修正し、floatサフィックス 'f' を付けるのみに留まりました。
修正後の全体のコードは [こちら](https://gist.github.com/lycoris102/db8f0b8e0f01b5d6c8a559d1c0015629) から見ることが出来ます。
先ほどと同じ様に、GameObjectにアタッチして実行すると、先ほど OpenProccesing 上で見たサンプルと同等のものが出力されます。

![unicessing3.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/ee96c6f6-4d83-2024-bd4b-984b83002b8b.gif)

# 各種ポストエフェクトを適応する

![unicessing4.gif](https://qiita-image-store.s3.amazonaws.com/0/102664/430eb0aa-803e-8daa-2207-4b834b5b7530.gif)

更にカメラに対してポストエフェクトを適応してみましょう。
`Post-Processing` を使用し、今回はBloom (発光表現) を適応します
Unity2018からはPackageManager経由で最新のバージョンを落とすことが出来ます。

<img width="734" alt="ooah_2.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/c5b8d1ee-b23b-766a-090c-36adab7398d6.png">

ここからは[公式ドキュメント](https://github.com/Unity-Technologies/PostProcessing/wiki)に従い作業を進めます。

* MainCamera　に `PostProcessLayer` をアタッチ
* 任意のオブジェクトに `PostProcessVolume` をアタッチ
* **任意のオブジェクトのレイヤーと `PostProcessLayer` で指定するレイヤーを合致させる**
* `PostProcessVolume` にて `Profile` を新規で追加する (or 指定する)
* `Profile` のファイルを選択し、 `Bloom` にチェックを入れる
* パラメータを調整する (主にIntensity)

<img width="418" alt="unicessing8.png" src="https://qiita-image-store.s3.amazonaws.com/0/102664/b6b437ff-02a9-f92c-b6f9-f30e266bd1d4.png">

上記の設定でBloomを指定することが出来ました。
この他にも [Camera Filter Pack](https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/camera-filter-pack-18433) や [ColorfulFX](https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/colorful-fx-44845) といったアセットが手頃に雰囲気を出せてオススメです。

# 最後に
![network_kanzenrikai.png](https://qiita-image-store.s3.amazonaws.com/0/102664/450c9c04-b049-7d33-0991-285e6bf17373.png)

[UnityRecorderを使う](https://qiita.com/lycoris102/items/6bf631b35d2769b2d475#%E4%BD%9C%E6%88%90%E3%81%97%E3%81%9Fparticle%E3%82%92unityrecorder%E3%81%A7%E5%87%BA%E5%8A%9B%E3%81%99%E3%82%8B) など、任意の手段で画像を書き出し、Illustrator等の任意のツールで加工してバナーにしました。

...正直 **バナー等の静止画に適応するだけであれば Processing で十分では？** ということに気付いた方もいらっしゃると思いつつ、Unityの資源を活かし、ゲームと組み合わせて演出を強化したり、各種プラットフォームに書き出したり出来るのは本当に魅力的だと感じています。

明日は @stdmouse さんによる[「[Unity] TestMesh Proで作った文字アニメーションをエディタ上でプレビュする」](c)です！楽しみですね！