📖

【Unity開発】変更に強いプログラム開発に役立つライブラリ&ドキュメント

2024/03/29に公開

Unityプログラミングをするにあたって役に立つライブラリをまとめてみました。
実装サンプルなど詳細には踏み込んでいません。

ゲーム開発に便利なライブラリ

※UnityやC#歴一年未満のため、間違いなどある可能性があります。指摘は大歓迎です。

UniRx

https://github.com/neuecc/UniRx
※現在では代替のR3というライブラリがあるため、開発終了したようです

用途

SubjectやReactivePropertyによるメッセージ駆動処理が簡単に実現できるライブラリです。
プレイヤーの操作受付や、エフェクト、効果音の再生などなど、あらゆる場面でメッセージ通信の仕組みを利用する必要が生じてくるので、使い方を知っておけばすぐに役に立つでしょう。

メリット

  • メッセージ送信側/受信側の依存を分離するObserverパターンによるメッセージ駆動処理が簡単に書ける
  • ReactivePropertyを使用して外部コンポーネントのプロパティ変更を簡単に監視できる

デメリット

  • 事後処理で適切にメッセージのSubscribeを停止しないとメモリリークの危険性が高まる

UniTask

https://github.com/Cysharp/UniTask

用途

非同期処理/マルチスレッド処理のためのライブラリです。C#でawaitやasyncを使うならば、必須と言ってもいいでしょう。

例えばUnityの非同期システムであるコルーチンはコルーチンが実行された処理結果を返却するのが難しいですが、コルーチンをUniTaskに置き換えることでそのような処理も簡単に書けます。

メリット

  • コルーチンよりも柔軟な非同期処理が書ける
  • 非同期処理やマルチスレッドをほぼゼロアロケーションで実現するため、パフォーマンスが高い

デメリット

  • WebGLではシングルスレッドしか使えないので、マルチスレッドの恩恵を受けられない。マルチプラットフォーム対応の場合、シングルスレッド用とマルチスレッド用両方のコードが必要

Extenject(旧Zenject)

https://github.com/modesttree/Zenject

元々Zenjectという名前のライブラリでしたが、Extenjectという名前に変えてUnity Asset Storeで頒布しているようです。ただし、namespaceや定数名は依然Zenjectという名前が使用されています。

用途

DI(依存性の注入)によって、インターフェースにインスタンスを注入できます。
クラス間の依存を分離するためにインターフェースを採用する場合、ネックになってくるのが「どこでインスタンスを生成するか」になります。いちいちインスタンス生成や取得のコードを書いたり、インスペクターにインスタンスを持つオブジェクトを指定するのも面倒です。

依存性注入をアトリビュートによって行えるので簡潔な書き方ができます。シーン内の全てのオブジェクトに対して注入したり、シーンを跨いだオブジェクトに対する注入もできます。

この考え方はユニットテストでも便利で、テスト用の入力を与えたい場合に役に立ちます。

メリット

  • インターフェースを利用しているクラスに対して簡単に依存性の注入が行える
  • シングルトンの代わりになる。インスタンスを管理している箇所が分かりやすくなる

デメリット

  • 依存性を注入してもデフォルトでは呼び出しが発生してから初期化するので、初期化の順番を考慮して利用する必要がある

ゲーム開発に役に立つドキュメント

Level up your programming with game programming patterns
https://unity.com/ja/resources/level-up-your-code-with-game-programming-patterns

SOLID原則やGoFのデザインパターンに触れ、ゲーム内で特に使用される設計パターンをサンプル付きで解説した無料のe-bookになります。英語ですが、デザインパターンとゲームとの繋がりがよく分からない時に読んだら勉強になりました。

まとめ

Unityでのゲーム開発はプログラムの変更が頻繁にある開発サイクル故に、急な仕様変更による既存部分の改修や新規機能を開発するにあたって、なるべく大部分の変更を避けながら開発したいわけです。

クラス間の結合は特に気を付ける必要があって、クラス間の結合が大きければ大きいほど単純な仕様変更であっても複数個所にまたがった膨大な修正作業を強いられる可能性が高く、設計を間違えれば生産性が下がってしまいます。その為、SOLID原則、デザインパターン、MVPモデルを意識した開発が必要になります。UniRxなどのライブラリを使用したメッセージ駆動処理によっていくつかの設計が実現しやすくなります。
抽象化によって再利用性を高めたクラス設計はインターフェースの活用が必須ですが、ZenjectによるDIパターンが多いに役立ちます。

また、インタラクティブな演出をするにあたり、多くの非同期処理も必要になってきます。UniTaskはコルーチンよりも柔軟に、簡潔に非同期処理が書け、パフォーマンスも良いとされるのでほぼ必須になってくるでしょう。

Discussion