読者です 読者をやめる 読者になる 読者になる

Zenjectに含まれてるサンプル その1

Unity DI Unity DI

kurihara-n.hatenablog.com

Zenjectについて前に書いたが、
アセットのパッケージ自体にサンプルが含まれているので、
それを見ていこうと思う。

サンプルは2種類あり、アセットをインポートしたままの状態であれば
Assets/Zenject/OptionalExtras
の下に
SampleGame1 (Beginner)
SampleGame2 (Advanced)
というフォルダがそれぞれある。

まず、SampleGame1(Beginner)から見ていく。
フォルダの中に、Asteroidsというシーンがあるので
このシーンを開く。

Runするとゲームが動きタイトル画面でクリックでゲームが始まる。
マウスで自機を動かし隕石を避けるゲーム。
f:id:kurihara-n:20170104223309p:plain

シーン構成

シーンの構成を見ていくと、
SceneContextがあり、ここにGameInstallerというInstallerスクリプトがあり、
Installersのリストに追加されている。
また、このSceneContextはScriptableObjectInstallerとして、
ゲームの設定が定義されているGameSettingsInstallerも設定してある。

Guiというオブジェクトからは、
GuiHandlerというコンポーネントがZenjectBindingsでBindされている。

Sceneというオブジェクトは、
背景と、ライト、カメラを持っている。特に触れることはない。

Shipというオブジェクトからは、
ShipというコンポーネントがBindされている。

Scriptable Object Installer

まず、
SceneContextのScriptable Object Installersに設定されているGameSettingsInstallerは、
ゲームの各種設定や、プレハブを持っているScriptableObjectになっている。
GameSettingsInstaller.csを見てみると
InstallBindings()にてそれぞれのインスタンスをBindingしている。
Container.BindInstance(****)というとこ。
これにより他の参照をしたいクラスで使うことができる。

Scriptable Object Installerのドキュメント
https://github.com/modesttree/Zenject#scriptableobject-installer

MonoInstaller

Bindingを行っているMonoInstallerであるGameInstaller.csを見ていく。
最初に、

        [Inject]
        Settings _settings = null;

という箇所があるが、
これがさっきのScriptableObjectInstallerでBindingした設定のインスタンスをとれるようにしているところ。
GameInstallerのSettingsはプレハブを持っている。

プレハブはBindFactoryでファクトリをBnidしており、よそでインスタンスを生成できるようにしている。

InstallAsteroids

            Container.Bind<ITickable>().To<AsteroidManager>().AsSingle();
            Container.Bind<IFixedTickable>().To<AsteroidManager>().AsSingle();
            Container.Bind<AsteroidManager>().AsSingle();

はAsteroidManagerをBindしている。
コメントにもあるが、

Container.BindAllInterfacesAndSelf<AsteroidManager>().To<AsteroidManager>();

と書くのとも一緒になる。

BindFactoryはScriptableObjectからプレハブを受けて、
Asteroidを生成できるようにわたしている。
WithGameObjectNameをつけると生成されるオブジェクトの名前を設定できる。
UnderTransformGroupは設定された名前のオブジェクトの子に設定していく。

InstallShip

最初に自機がクラッシュした時のSignalをバインドしている。

            Container.BindSignal<Signals.ShipCrashed>();

Signalはイベントと同じように使える。
https://github.com/modesttree/Zenject/blob/master/Documentation/CommandsAndSignals.md#signals

ちなみに、SignalのListenを残している状態でSignal自体のDisposeが走ると
Assertになってしまう。
Assertが書いてあるSignal1.csからSignal6.csというファイルに、
要らないならコメントアウトしてね、って書いてあるので気になるならコメントアウトしよう。

他にはStateFactoryと、各ステートのfactoryがBindFactoryされてる。
ステートは
ShipStateWaitingToStart
ShipStateDead
ShipStateMoving
Stateを使っているのはShipオブジェクトだが、
これはシーンに配置されていて、ZenjectBindingによってBindingされている。

InstallMisc

GameControllerをはじめ、
もろもろのクラスのバインディングを行っている。
爆発などのプレハブもBindFactoryしていて、
Ship死亡時のステートからcreateが呼ばれている。

InitExecutionOrder

処理順の制御を行っている。
これはUnityのExecution Orderと同じように使えるものと思っておけばいい。
https://github.com/modesttree/Zenject#update--initialization-order