【Unity】Endless Runnerについて

# はじめに

UnityでRunゲームを作成しようと思った際に、何か参考にできる情報が無いかを探していたら、`Endless Runner - Sample Game`が見つかりました！

Unityが作成したサンプルゲームです。
2020/05/16現在、AssetStoreからダウンロードする事が可能です！
[アセットのページ](https://assetstore.unity.com/packages/essentials/tutorial-projects/endless-runner-sample-game-87901)

# Unityサービスについて

広告、分析、IAPを簡単に実装する事ができるサービスです。
サービスダッシュボードでいくつかの詳細を構成し、少量のコードを記述するだけです。

## IAPの統合に使用されるコード

`IAPHandler.cs`にIAPを統合するためのコードが記載されています。

## 広告の処理に使用されるコード

広告に関するコードは`AdsForMission.cs`および`UnityAdsinitializer.cs`に記載されています。

## 分析コードについては
いくつかの良い例が`GameManager.cs`にあります

# ゲームマネージャー
`GameManager.cs`はゲームの全体的なフローを制御するクラスです。

GameManagerは、シングルトンと呼ばれるデザインパターンを使用します。シングルトンパターンは、ゲーム内に特定のクラスのインスタンスが1つしかないことを保証する方法です。これは、クラスにGameManagerなどの重要な責任がある場合に役立ちます。また、パブリック静的参照を使用して、他のクラスがこのインスタンスに簡単にアクセスできるようになります。

GameManagerも有限状態マシンの例です。有限ステートマシンは、ゲームが常に1つの状態のみになることを保証し、この状態が変化したときに何が起こるかを管理します。Trash Dashの状態には、スタートメニューの表示、ゲームのプレイ、ゲームオーバースクリーンの表示の3つがあります。有限状態機械は、ゲームの全体的な流れから個々のキャラクターの振る舞いまで、ゲームでの動作を管理する一般的な方法です。
シングルトンおよび有限状態マシンのコードを確認するには、`GameManager.cs` を調べてコメントを読んでください。3つの状態を開始、実行、終了するためのコードは、`LoadoutState.cs` 、`GameState.cs` 、`GameOverState.cs`の各ファイルにあります。

## シングルトンについて
[参考ページ](https://www.hanachiru-blog.com/entry/2018/09/26/010232)

# オブジェクトプーリング

Trust Dashでは、1回のプレイセッションで数百のコインが発生することがあります。実行時に非常に多くのオブジェクトをインスタンス化して破棄すると、パフォーマンスに負担がかかる可能性があります。比較的コストのかかるコードが含まれ、頻繁で時間のかかる[ガベージコレクション]（https://geechs-magazine.com/tag/tech/20160229）につながる可能性があります。

このオーバーヘッドを削減するために、Trash Dashは[オブジェクトプーリング](https://doruby.jp/users/ino/entries/%E3%80%90Unity%E3%80%91%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E3%83%97%E3%83%BC%E3%83%AA%E3%83%B3%E3%82%B0%E3%81%A7%E3%82%AA%E3%83%96%E3%82%B8%E3%82%A7%E3%82%AF%E3%83%88%E7%AF%80%E7%B4%84%E8%A1%93)と呼ばれる手法を使用します。オブジェクトプーリングは、オブジェクトを作成して破棄するのではなく、オブジェクトを一時的に非アクティブ化し、必要に応じてリサイクルする手法です。

ゲームが始まると、いくつかの非アクティブなコインGameObjectが生成され、「プール」に配置されます。新しいコインが必要になると、プールから1つが要求され、有効になります。コインが収集されるか画面を離れると、コインは無効になり、プールに戻されます。

Trash Dashのオブジェクトプーリングコードを確認するには、`TrackManager.cs` 、`Coin.cs` 、および`Pooler.cs`をご覧ください。
Unityでのオブジェクトプーリングの一般的なガイドについては、[Unity Learnサイト](https://learn.unity.com/tutorial/object-pooling#)のこのチュートリアルを参照してください。

#テクニック
アーキテクチャの決定は、通常、ゲームの多くのクラスまたは部分に影響を与えますが、テクニックの焦点は小さくなります。テクニックは単一の関数またはファイルにのみ影響する可能性がありますが、それでも問題の解決に役立ちます。
Trash Dashで使用されているいくつかのテクニックを見て、それらが解決する問題を見てみましょう。

## 原点リセット
宇宙探査ゲームやゴミ箱ダッシュなどの「無限」ゲームなど、プレイヤーが遠くまで移動するゲームでは、開発者はプレイヤーの位置の処理方法を決定する必要があります。プレーヤーのGameObjectを移動するだけの場合、プレーヤーの`transform.position`の値は時間の経過とともに次第に高くなります。これは、浮動小数点不正確性と呼ばれるものによる問題を引き起こす可能性があります。

浮動小数点の不正確さは、浮動小数点数の値が大きいほど、精度が低くなることを意味します。これはコンピューターが数値データを保存する方法の制限であり、Unityに固有のものではありません。プレイ可能な領域が大きい、または無限のゲームでは、位置を格納するために使用される浮動小数点数が問題を引き起こすほど大きくなる可能性があります。
GameObjectの位置に不正確な値があると、動き回ったり、ちらついたり、飛び出したりするように見えることがあります。

この問題を解決する方法はいくつかありますが、どれが最適かはゲームによって異なります。Trash Dashでは、**origin reset**と呼ばれる手法を使用してこの問題を解決しています。つまり、プレーヤーがワールドの原点（つまり、ワールドの位置0、0、0）を超えて特定の距離を移動すると、シーンのすべてが原点に向かって移動します。これにより、位置に使用される値が常に低くなり、不正確になりにくくなります。原点リセットはシームレスに行われ、プレイヤーはそれを認識しません。
原点リセット手法に使用されるコードを確認するには、`TrackManager.cs`を見てください。

## 湾曲したワールドシェーダー
Trash Dashでは、プレーヤーの前にトラックセクションをスポーンし、プレーヤーの後ろにあるトラックセクションを削除して、無限のトラックを作成します。プレイヤーがずっと先を見ることができる場合、事前に多くのトラックセクションをスポーンする必要があります。これにより、パフォーマンスの問題が発生する可能性があります。

これに加えて、世界はコイン、障害物、キャラクターでいっぱいです。繰り返しになりますが、プレイヤーがそれらの前に長い距離を見ることができる場合、Unityは、これらのオブジェクトがすべて、対話するのに十分近くなる前に画面に描画する必要があります。これは、特にモバイルで、パフォーマンスの問題を引き起こす可能性もあります。

この問題を解決するために、世界は地平線でプレイヤーから離れて曲がります。これは無限の世界の錯覚を作成し、トラックピースのスポーンを非表示にし、プレイヤーがそれらに近づくまで、コインや障害物をスポーンする必要がないことを意味します。

シーンを調べると、世界の実際のジオメトリは湾曲しておらず、平坦であることがわかります。カーブしたエフェクトは、シェーダーによって作成されます。シェーダーは、オブジェクトを画面に描画する方法をUnityに指示するコードです。この場合、シェーダーはレベルが湾曲した場合の外観を計算し、その計算に基づいてスクリーンにピクセルを描画する場所をUnityに通知します。

これがどのように機能するかを確認するために調べるファイルは、`WorldCurver.cs` と`CurvedCode.cginc` です。
[シェーダーコードのガイド](https://docs.unity3d.com/Manual/SL-VertexFragmentShaderExamples.html?_ga=2.268132362.580340774.1589440344-137449421.1585459671)

# 参考文献
Trash Dashには、アプローチとテクニックのさらに興味深い例がいくつかあります。魚の回転に使用されるシェーダー、AssetBundlesを使用してキャラクターとテーマをロードする方法、およびプレーヤーデータが保存される方法を見てみましょう。
パフォーマンスの最適化の詳細については、[UnityのLearnサイト](https://learn.unity.com/search?k=%5B%22tag%3A5816095d0909150016dc7b17%22%5D)でこれらの記事を読んでください。
Unityを使用してモバイルゲームを作成する方法の詳細については、[Unity Learnサイト](https://learn.unity.com/search?k=%5B%22q%3AMobile+%26+Touch%22%5D)のこのセクションをご覧ください。