やらなイカ?

たぶん、iOS/Androidアプリの開発・テスト関係。

Unity #Zenject完全に理解した に行ってきました

株式会社ミクシィさんで開催された『Unity Zenject完全に理解した』に行ってきたメモ。

connpass.com

配信アーカイブもあります。すばらしい。はじめ機材トラブル等ありますが解消します(ネタバレ

www.youtube.com

Zenjectとは、オープンソースのUnity向けDI(Dependency Injection)フレームワークです。 Zenject以前に「DIをよく知らない」という方は、まず、とりすーぷさんの『インタフェースの使い方』から見るのがいいでしょう。ここで、DIというものがなぜ必要か、なにを解決してくれるものか、がわかるはずです。

もし『インタフェースの使い方』が何を言っているのかわからないのであれば、今日のところはUnity仙人さんの『Zenjectはじめの一歩:ゲームデータをScriptableObjectでInject!』だけにしておくのがいいのではないでしょうか。

この手のツール・フレームワークは、手段から入ってしまうとマズロー*1の言う

ハンマーを持つ人にはすべてが釘に見える

状態に陥りがちです。

Zenjectのような強力な手段を乱用すると、結果的にそのデメリットだけがプロジェクトに残ってしまうことになりかねません。(完全に、とは言わないまでも)ある程度は理解した上で導入していくことをおすすめします。

ゲーム案件にZenject導入した経験を語る

かせ(@KaseliaePenguin)さん

実際のプロダクトにZenjectを導入した経緯(目的)、試行錯誤したこと、どの範囲に適用すべきか、適用する上での注意点など盛りだくさん。

  • SceneContextを4階層(System, Data, Env, Logic)にしてそれぞれの扱う範囲を明確化し、切り替え(本番とデバッグの置き換え等)を制御
  • Bind時のAsSingle(), AsCached(), AsTransient()の違い
  • [Inject]を書いたフィールドのバインドはnew()の後に行なわれる
  • SceneContextの理解が大事
  • InjectするものにはInterfaceを切り、InterfaceをInjectすること
  • Bindはリフレクションを使うので遅い
  • 真価は運営フェーズに入ってからのはず

speakerdeck.com

文脈を操る 美しきZenjectプロジェクトからの眺め 〜Contextの扱い方と活用方法〜

Mikito Yoshiya(@mikito0521)さん

4種類あるContextの階層構造と、またそれを入れ子にできる話、実際にリリース版とデバッグ用のContextを切り替える例など。

  • Contextを意味のある単位に分割して切り替える
  • ProjectContext, SceneContext, SceneDecoratorContext, GameObjectContext
  • それぞれ入れ子にできる
  • IDisposableを実装すると、Contextが破棄されたタイミングでDispose ()を呼んでくれる
  • 大事なのはInstallerの設計。Contextとの組み合わせ
  • 依存がわかりにくくなるので、SceneContextは二階層くらいにしておく。小さいものはGameObjectContextにまわす

www.slideshare.net

インタフェース完全に理解した

とりすーぷ(@toRisouP)さん

C#のInterfaceの話。設計の話のほか、拡張メソッド、明示的な実装を書けるといった話。

  • Interfaceには必ず利用者がいる。利用者側のPackageに置く。利用者側でコントロールできる
  • 拡張メソッドに実装を書くことができる。traitっぽく使える
  • structにInterfaceをかぶせる(実装する)ことができる
    • IEquatable<T>を実装すると、Equals()の振る舞いを自分で書ける
  • 明示的な実装。InterfaceName.MethodName()と書ける。すると、Interfaceにキャストしないと呼べない

niconare.nicovideo.jp

Zenject完全には理解できなかった〜実運用におけるアンチパターンとその回避策〜

のたぐす(@notargs)さん

実運用で問題となるアンチパターンの話。Zenject自体への依存を下げるMethod injectionや、処理負荷を考慮した適用範囲の話など。

  • ZenAutoInjecter
  • Method injection: フィールドでなく初期化メソッドに[Inject]を指定できる
  • MonoBehaviorをInjectするとき、FromComponentInNewPrefab()でなくFactory経由で行なう
  • 頻繁に使うものはプールする、そもそもDIしない
  • pure C# classにのみ適用するほうがいい
  • Zenjectはハイリスク、ハイリターン

docs.google.com

Zenjectの機能をご紹介 〜テストの巻〜

@nozomin770 さん

Zenjectを適用したプロジェクトのEdit mode testで使うZenjectUnitTestFixtureおよび、Play mode testで使うZenjectIntegrationTestFixtureの話。

※スライドupされたら貼ります

Zenjectはじめの一歩:ゲームデータをScriptableObjectでInject!

Unity仙人(@lucifuges)さん

クラス設計など行なう前提でなく、データをScriptableObjectで持ち、それをScriptableObjectInstallerで切り替える話。

docs.google.com

所感

実際のプロダクトにZenjectを導入した経験談なども語られ、とても勉強になりました。皆さん、ただ「便利だよ」でなくデメリットにも言及されており、とても地に足の着いた内容だと感じました。 また、ContextやInterface、テストなど、それぞれフォーカスされた箇所が異なるセッションで構成されていたのもよかった。

自分ではまだ、DIが生きるほどの規模のものを作っていないのですが、今回の知見を取り入れて良い設計を目指していきたい。

参考

Unityゲーム プログラミング・バイブル

Unityゲーム プログラミング・バイブル

*1:心理学者のアブラハム・ハロルド・マズロー。欲求5段階説の人