はじめに
この記事は クラスター Advent Calendar 2021 の22日目の記事です。
昨日は @compile3 さんの「仕事で振り返るclusterの3年間」でした。私の知らない時代のclusterについて色々と書いてあって楽しくclusterの歴史を振り返れました。
今年の1月からクラスター株式会社に所属してclusterのUnity Clientの開発をしている sansuke です。
さてclusterのクライアントアプリについて、iOSやAndroidの設計や機能開発の話については他のメンバーが書いていますが、Unity部分の開発全般について紹介している人はそんなにいませんでした。(私調べ)
そこで、今回は現在のclusterのUnityクライアント部分、特にGUI周りの設計思想や使われている技術について、大まかに紹介していこうと思います。
Unityクライアントの全体構成
Unityクライアントの設計は(ほぼ)以下の図ような構成になっています。
その中でも、GUIは (基本的には) MVPをアーキテクチャとして採用しています。
MVP vs MVVM
MVPとよく比較されるアーキテクチャにMVVMがあると思います。
clusterのUnityクライアントがMVVMではなくMVPを採用している背景としては
-
DIコンテナにZenjectを採用しており、View(MonoBehavior)へのInjectをできるだけしたくない
-
Viewから他のクラスへの依存をできるだけ減らし、Viewを含むPrefab単体での動作確認を行いやすくしたい
という理由があります。
1の、View(MonoBehavior)へのInjectをできるだけしたくない理由としては、前提としてZenjectはコンストラクタへのInjectionを推奨しています。しかし、MonoBehaviorはコンストラクタへのInjectをすることができないため必然的にメソッドInjectionを使うことになり、循環依存が発生しやすくなるといったことがあります。
UniRx, UniTask
Model, ViewからPresenterへのデータバインディングには UniRx を使っています。1
UniRxはModelとPresenterだけではなく、依存関係を逆転させたい場所や、連続的なデータの加工をしたい場合に使われる事が多いです。
UniRxを使用している箇所が多くなるとコードベースが複雑になりがちですが、上記で紹介した設計などのおかげで比較的綺麗に保たれていると感じています。2
また、Presenterなどの依存元から依存先に対しての非同期処理の呼び出しは UniTask を使って行うことが多いです。
複数プラットフォーム対応
clusterは Desktop (Windows, Mac) / Mobile (iOS, Android) / VR (PCVR, Oculus Quest 2) に対応しています。
これら全てのプラットフォームに別々の画面を提供するのはコストが非常に高いため、以下のようにNested Prefabの機能を使って、ある程度画面の共通化を行っています。
コードの方もDesktopとMobileに関しては、UI上の操作や表示方法などが違わない限りは、基本的に同じコードベースを使用できるように作っているため、DesktopとMobile両対応のためのコストは比較的少なくなっています。
また、Mobileでは ピクチャー イン ピクチャー の機能を使い、Unity側からネイティブアプリ側の機能に切り替えを行うようにすることで、モバイル部分の開発コストを下げたりもしています。
最近はこれと合わせて、VRとそれ以外のプラットフォームのコードをできるだけ共通化するようにして、さらに開発のスピードが上がるような取り組みも行われています。
さいごに
ざっくりとですが、UnityのGUI周りの開発の紹介をしてみました。
clusterのUnity開発ではこの他にも様々な機能開発を行なっています。その辺りは、他のメンバーがアドベントカレンダーの記事にしているので、ぜひ見てみてください!
そして、clusterでは一緒に開発に携わってくれるメンバーを大募集中です!もし興味を持たれた方は採用ページまでどうぞ!
明日は、@anoriqqさんの「ジュニアなエンジニアを助けたクラスターのメンタリング」です!