Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9743

VContainer の導入と基本的な使い方 ver 0.9.0 ( 備忘録 )

$
0
0

自分用の備忘録記事

最近新しくリリースされたシンプルなDIコンテナライブラリのVContainerの導入方法をメモ

環境

Unity 2018.4.14.f1
VContainer ver 0.9.0

導入方法

GitHubから直接UnityPackageをDLしてプロジェクトにインストールする方法とUnityPackageManagerでインストールする方法がある、今回はUnityPackageを直接インストールする方法をとる

GitHubのリリースページから0.9.0のUnityPackageをDLし、プロジェクトにインポート
この時、manifest.jsonに nuget.mono-cecil": "0.1.6-previewの指定を追加

これで特にエラーが無ければまずは導入成功

簡単なサンプル

次にVContainerを利用した簡単なサンプルを作成します。
VContainerには疑似的にMonoBehaviourのStartやUpdateイベントと似た様な処理を行うことが出来る仕組みがあるので( MonoBehaviourを利用しないクラスでMonoBehaviourのUpdate同様に毎フレーム何かの処理をする等を行えるように )そのサンプルとMonoBehaviourを継承した通常のGameObjectのコンポーネントから利用する方法の二通りを作成します。

HelloWorldServiceの作成

先ずはゲームを通じて利用するHelloWorldServiceクラスを作成します、呼び出し元確認用にstringで引数をとりいつ呼ばれたかをコンソールに表示します、 このクラスはMonoBehaviourを継承しないクラスとします。

usingUnityEngine;publicclassHelloWorldService{publicvoidHelloWorld(stringtext){Debug.Log($"{text} : HelloWorld");}}

GameLifetimeScopeの作成

Zenjectで言うところのSceneContextを作成します
ProjectWindowで右クリック Create > C# Script でファイル名に *LifetimeScopeと記述すると自動でテンプレートスクリプトを作成します。

usingVContainer;usingVContainer.Unity;publicclassGameLifetimeScope:LifetimeScope{protectedoverridevoidConfigure(IContainerBuilderbuilder){}}

この段階ではまだテンプレートのままです、いったん先に進みます。

GamePresenterの作成

MonoBehaviourを継承していないクラスでMonoBehaviourのStartやUpdateのイベント同様な処理を行えるクラスを作成します。

LifeCycleのイメージ図

usingVContainer.Unity;publicclassGamePresenter:IInitializable,IPostInitializable,IFixedTickable,IPostFixedTickable,ITickable,IPostTickable,ILateTickable,IPostLateTickable{privatereadonlyHelloWorldServicehellowWorldService;publicGamePresenter(HelloWorldService_helloWOrldService){hellowWorldService=_helloWOrldService;}// Start()直前に呼ばれる.publicvoidInitialize(){hellowWorldService.HelloWorld("Initialize");}// Start()直後に呼ばれる.publicvoidPostInitialize(){hellowWorldService.HelloWorld("Postinitialize");}// FixedUpdate()直前に呼ばれる.publicvoidFixedTick(){hellowWorldService.HelloWorld("FixedTick");}// FixedUpdate()直後に呼ばれる.publicvoidPostFixedTick(){hellowWorldService.HelloWorld("PostFixedTick");}// Update()直前に呼ばれる.publicvoidTick(){hellowWorldService.HelloWorld("Tick");}// Update()直後に呼ばれる.publicvoidPostTick(){hellowWorldService.HelloWorld("PostTick");}// LateUpdate()直前に呼ばれる.publicvoidLateTick(){hellowWorldService.HelloWorld("LateTick");}// LateUpdate()直後に呼ばれる.publicvoidPostLateTick(){hellowWorldService.HelloWorld("PostLateTick");}}

実装しているインターフェースは其々コメントに書かれある通りのタイミングに呼ばれます。

TestObjectの作成

最後にMonoBehaviourを継承したTestObjectクラスを作成します

usingUnityEngine;usingVContainer;publicclassTestObject:MonoBehaviour{privateHelloWorldServicehelloWorldService;// コンテナから取得.[Inject]publicvoidConstruct(HelloWorldService_helloWorldService){Debug.Log("Inject");helloWorldService=_helloWorldService;}voidUpdate(){if(Input.GetKeyDown(KeyCode.Space)){helloWorldService.HelloWorld("TestObject");}}}

Update時にスペースキーを押下したらHelloWorldSericeのHelloWorld()を呼び出すようにします。

Sceneの作成

次にシーンを作成します
先ずコンテナを実装するためにGameLifetimeScopeオブジェクトを作成します、Hierarchy上で右クリック Create Empty で GameObjectを生成、GameLifetimeScope.cs をアタッチします。

VContainer_0.JPG

このまま実行しても何も起きないので GameLifetimeScope に手を加えます

usingVContainer;usingVContainer.Unity;publicclassGameLifetimeScope:LifetimeScope{protectedoverridevoidConfigure(IContainerBuilderbuilder){builder.Register<HelloWorldService>(Lifetime.Scoped);builder.RegisterEntryPoint<GamePresenter>(Lifetime.Singleton);}}

利用される側のHelloWorldServiceクラスをbuilderに登録、その次に利用する側のGamePresenterをbuilderに登録します。

そして実行
コンソールが以下の様になれば正常に動作しています、Hierarchy上にはMainCamera、DirectionalLight、GameLifetimeScopeオブジェクトの3つだけでありこのログを読んだオブジェクトがシーン上に配置されていないことがわかります。

VContainer_1.JPG

次にGameObjectから利用する場合です。
GameLifetimeScopeに以下のように手を加えます。

usingUnityEngine;usingVContainer;usingVContainer.Unity;publicclassGameLifetimeScope:LifetimeScope{[SerializeField]TestObjecttestObject;protectedoverridevoidConfigure(IContainerBuilderbuilder){builder.Register<HelloWorldService>(Lifetime.Scoped);builder.RegisterEntryPoint<GamePresenter>(Lifetime.Singleton);// TODO : GameObjectとの紐付け( これ以外の方法があるかはまだわからない ).builder.RegisterComponent(testObject);}}

次にシーン上にTestObjectを配置します。
この時GameLifetimeScopeのInspectorからTestObjectをセットします。
VContainer_2.JPG

これで実行

以下のようにコンソールが表示されれば成功です、スペースキーを押下したときに TestObject : HelloWorldが表示されてるのが確認できるはずです。
VContainer_3.JPG

以上でとりあえずVContainerを導入及び簡単なサンプルの作成までの手順です

ここに一応サンプルプロジェクトを配置しています見る必要はないと思いますが

より詳細の情報やZenjectのAPIとの対応表を確認したい人は開発者のGitHubページにて確認できます

あとがき

MonoBehaviourのコンポーネント側からコンテナに登録したクラスをInjectする時の方法がいまいちよくわかってない、ソースコードにもある通りLifetimeScopeに[SerializeField]でInjectを要求してるコンポーネントを紐付けないとできない?
詳しい方いたらご教示おねがいします


Viewing all articles
Browse latest Browse all 9743

Trending Articles