[Unity] Unity1週間ゲームジャム (逆) にて実装した演出をまとめる

# 🖥開発環境
Untiy2019.3.1f1

# 📝この記事の概要
ゲームの投稿サイト [unityroom](https://unityroom.com/) にて開催された [1週間ゲームジャム](https://unityroom.com/unity1weeks) というイベントに参加しました。お題は「逆」で逆方向からもノーツが流れてくる音ゲーを作成しました。

[△atled | フリーゲーム投稿サイト unityroom](https://unityroom.com/games/atled)

<img width="490" alt="スクリーンショット 2020-03-01 22.56.51.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/5a52d35c-d0b8-361e-bdec-dba30ad958bd.png">

<img width="482" alt="スクリーンショット 2020-03-01 23.16.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/cd826cf4-1632-bb07-5497-0c3736afa079.png">

今回はこのゲームの演出を作る際に使った技術を紹介します。
(音楽ゲームの作成方法/ロジックに関しては今回記載しません🙇‍♂️)

# Light2D / ShadowCaster2D
Light2DおよびShadowCaster2Dは2Dプロジェクトにおけるライティングおよび影描写を実装するためのコンポーネントです。ビルドイン(標準)のRenderPipelineでは使用することができないため、UniversalRenderPipelineを使用する必要があります。使い方など、導入/詳細は以下のスライドに記載してあります。

* [楽しい！LWRP + Light2D💡 – Unity Learning Materials](https://learning.unity3d.jp/4055/)
* [URP + ShadowCaster2D 2Dプロジェクトで影を出す](https://speakerdeck.com/lycoris102/cast-shadow-with-urp-in-2d-project)

📝GlobalLight の Intensity をアニメーションさせることで擬似的なフィードインを実装しています。

![2020-03-07 14.50.24.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/b5e790f2-e120-13c3-84ae-100f156ac0ac.gif)

📝影を出すことで画面にメリハリが生まれ、オブジェクトに対する注意を引きつけることができます。

![2020-03-07 14.47.05.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/e6aedd2c-e1ba-59ee-6257-b564531e13b6.gif)

# PostProcess
[Unity - Manual: Post-processing](https://docs.unity3d.com/Manual/PostProcessingOverview.html)

ポストプロセス(事後処理)を使用することでレンダリングされた画面に対して様々なエフェクトを加えることが出来ます。UniversalRenderPipeline にて PostProcess を適応するには以下の手順を踏みます。

* `Camera` コンポーネントの `Rendering > PostProcessing` のチェックを有効にする
* `Volume` コンポーネントを追加する
* `Profile` を追加する ( `NEW` から新規作成可能 )
* 追加したいエフェクトを指定する

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/d106020a-a134-198a-542d-1e4b56f05ad0.gif" height=400></img>

## Bloom
明るい物体から光が滲むような効果を追加できます。
(以下、効果が分かりやすいように実際のゲームより Intensity を上げています)

![2020-03-07 14.13.15.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/7b2913cb-37c7-ce25-9d64-e54c8bfd5cd5.gif)

## Vignette
画面角にぼんやりと掛かっている黒枠のことです。
これにより、ムードある雰囲気を持たせ、トンネル効果(画面中央に視線を集める)を狙います。

![2020-03-07 14.10.19.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/1463de27-e0df-a961-c11d-4f428d10e049.gif)

## ColorLookup
画面に出力された色を LookUpTexture を基に他の色に変換して置き換えます。
色味を統一させることで画面全体の雰囲気作りに役立てます。

![2020-03-07 14.33.01.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/451d3366-09ab-4b17-de4a-201db14910c7.gif)

[1000+ Fast Post Processing 1K Styles Mobile and PC + LUT Export - Asset Store](https://assetstore.unity.com/packages/vfx/shaders/fullscreen-camera-effects/1000-fast-post-processing-1k-styles-mobile-and-pc-lut-export-111954?locale=ja-JP) というアセットに内包されるテクスチャを指定しています。今回は曲ごとに異なるテクスチャを適応し、雰囲気をガラッと変えることを試しています。

![2020-03-07 14.42.32 (1).gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/2a8358d0-943b-ee3e-5357-a5d2c5a1497d.gif)

```csharp
// ColorLookupのテクスチャを動的に変更するコード例
ColorLookup colorLookup;
if (GetComponent<Volume>().profile.TryGet<ColorLookup>(out var tmp))
{
    colorLookup = tmp;
}
colorLookup.texture.value = texture;
```

## ChromaticAberration
ChromaticAberration(色収差/色ずれ表現)もPostProcessにて適応することが可能です。

![2020-03-07 14.55.46.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/87095e71-2a39-aeb2-0bc1-ece740782128.gif)

# Cinemachine
Cinemacineの導入方法や2Dプロジェクトへの適応に関しては以下を参照ください。
[よーし、パパ Cinemachineを2Dプロジェクトに適応して遊んじゃうぞー – Unity Learning Materials](https://learning.unity3d.jp/2976/)

全体的に画面が大人しくなったので、動く要素を作り画面が死なないようにするために
Noiseを有効にし、常にカメラが(ゲームに影響しないレベルで)ゆっくりブレる演出を導入してみました。

![2020-03-07 22.56.40.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/7dabd59b-3eb2-37c5-c80b-5410be006bcc.gif)

Cinemachineを使うことでノーコーディングで実装可能かつ、座標移動処理の後にノイズ効果が適応されるので、他のカメラ移動処理とコンフリクトすることもなくなります。

<img width="514" alt="Main - Unity1Week202002 - WebGL - Unity 2019.3.1f1 [PREVIEW PACKAGES IN USE] &lt;Metal&gt; 2020-03-07 20-56-18.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/2f7322d0-378f-5d6b-45a0-246655e22d4e.png">

# Timeline/DOTween
タイトルやチュートリアル、楽曲開始時/終了時のカットイン演出は [Timeline](https://docs.unity3d.com/ja/2018.4/Manual/TimelineOverview.html) を使っています。複数のオブジェクトの参照を跨ぐものが作りやすい、Editor上で動きを確認しやすいといった恩恵がありました。

<img width="461" alt="Main - Unity1Week202002 - WebGL - Unity 2019.3.1f1 [PREVIEW PACKAGES IN USE] &lt;Metal&gt; 2020-03-07 20-57-58.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/8286c0f8-a65a-b2e2-b2f5-d471ce6640cb.png">

基本的には AnimationTrack に動かしたい GameObject を指定し、Recを利用してプロパティの変更を記録し Timeline 上で演出を作っていきました。

<img width="1141" alt="Main - Unity1Week202002 - WebGL - Unity 2019.3.1f1 [PREVIEW PACKAGES IN USE] &lt;Metal&gt; 2020-03-07 21-07-30.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/9106e2c6-3a70-59c3-17b6-7f8c20e9db9a.png">

一方、判定の表示やスコア/リザルトのテキスト増加など、ゲーム中の細かい演出やAnimationで表現できない箇所は [DOTween](http://dotween.demigiant.com/index.php) を使用しています。スコアのカウントアップ演出に関して、DOTweenの標準での拡張メソッドとして存在せず、 `DOTween.To` を使って自前で実装していたのですが、 @RyotaMurohoshi さんの以下の記事がとても良かったのでそのまま使用させていただきました。

[DOTweenでカウントダウン・カウントアップのアニメーション - Qiita](https://qiita.com/RyotaMurohoshi/items/f7312e802f7698e42cd0)

リザルト画面ではTimelineとDOTweenの合わせ技を使い、演出の大まかな流れはTimeline/スコアのカウントアップはDOTweenを使うことを試しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/30f38d6d-4031-54f5-ff7f-889588def899.gif" height=500></img>

Unity2019からTimeline上で任意の処理を呼ぶことが出来る Signal という機能が実装されましたが、今回はそちらを使って対応しています。Signalの具体的な使い方は以下を参照ください。

[分かった気になる! Timeline Signals – Unity Learning Materials](https://learning.unity3d.jp/2337/)

# TextMeshPro
TextMeshProは従来のuGUIのTextコンポーネントと比較して豊かな表現が可能となっています。今回は `SpacingOptions > Character` (文字間隔) をアニメーションさせる表現を導入しました。

![2020-02-27 18.22.37.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/5283e6d2-b7b1-7587-d6b6-f8368fbd1902.gif)

余談ですが今回のゲーム内の全ての文字に対して、フリーフォント [M+](https://mplus-fonts.osdn.jp/) の `mplus-1p-light` を使用しています。

# ParticleSystem
ユーザの入力に対するフィードバックとしての判定時エフェクトはParticleSystemで作成しています。
円は `Color over Lifetime` でフェードアウトさせつつ `Size over Life time` でやや余韻が残るような拡大の仕方 (easingだと `easeOutBack` に近いもの) を指定しました。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/c9b76389-26ac-bdfd-9ccf-26061e6d92f9.gif" height=500></img>

粒子は `Renderer > RenderMode` で `Streched Billboard` を指定することで四角のテクスチャを引き伸ばして表現し、また `Limit Velocity Over Lifetime` で速度を減速させることで間延びしない小気味良い表現になったと思います。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/c55cf1bd-6544-9f58-bab7-30a78a368aca.gif" height=500></img>

# ShaderGraph
背景はShaderGraphで実装しています。

<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/a86091a5-bd67-346d-ba4e-43b9a29a81e1.png" height=300></img>

Volonoiノードのおかげで楽にボロノイ表現が実装できることを知り、背景として使用してみました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102664/1d267821-eb56-0269-1ee6-cf5225c24122.png)

[Volonoi.json](https://gist.github.com/lycoris102/0bcd540dae0440068964149acbec6247)

参考: [【Unity】LWRPの2Dパイプラインで、ShaderGraphを使ってみる - テラシュールブログ](http://tsubakit1.hateblo.jp/entry/2019/07/10/230000)

# 最後に
Unityの機能で対応できる演出は増えてきたと思います。
覚えることは大変ですが、一度覚えてしまえば色々な場面で使えるのではないでしょうか。
この記事がUnityで演出を作るときのきっかけや参考になりましたら幸いです。

(この記事読んで興味持った方、もし良かったら遊んでいただけますと興奮します🙇‍♂️)
[△atled | フリーゲーム投稿サイト unityroom](https://unityroom.com/games/atled)