Slide 1

Slide 1 text

Zenject Optionalアレコレ いも(@adarapata) 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 2

Slide 2 text

自己紹介 いも(28) @adarapata XFLAG クライアントエンジニア スマブラSPはガオガエン adarapata.com 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 3

Slide 3 text

今日の話 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 4

Slide 4 text

Zenject OptionalExtras ZenjectはDIとは直接関係ないけど便利な機能をいく つか提供している。 公式ドキュメントはあるけど、あまり日本語記事はな いので使われてるかどうかはわからない。需要はない かもしれない。 でも話そう。 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 5

Slide 5 text

Optionalな方々 TestFramework Signals MemoryPoolMonitor Re ection Baking 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 6

Slide 6 text

TestFramework みんな大好きテスト機能の提供。現在は3種類のテス トに区分されている。 UnitTest IntegrationTest SceneTest Unity標準のテストクラスではDiContainerが用意さ れていないのでDIしているコードのテストが書きづ らい。なのでZenjectのテストクラスを使う。 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 7

Slide 7 text

UnitTestとIntegrationTest https://speakerdeck.com/adarapata/zenjecttotesuto 以前に書いたのでこちらもどうぞ。 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 8

Slide 8 text

SceneTest 最近追加されてたテスト。シーンをサッと呼べる機能 が追加されている public class FooSceneTest : SceneTestFixture { [UnityTest] public IEnumerator TestScene() { yield return LoadScene("FooScene"); // FooシーンにFooクラスがバインドされてるか? Assert.That(SceneContainer.HasBinding()); } } 複数のシーンも一気に読み込める 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 9

Slide 9 text

こんなときに便利そう Zenject使いつつテスト書きたいとき というか書くならContainerを扱うのでほぼ必須 基本的にはUnitTestとIntegrationTest書いておけば なんとかなりそう SceneTestは、そもそもシーン単位でどういう風に 書いてくとベストなのかは模索中 UIにイベント流す機能もないので自前でがんば る 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 10

Slide 10 text

Signals いわゆるPub/Subメッセージ機構 SignalBusを使ってメッセージを発行・購読できる UnityだとPub/SubはUniRx.MessageBrokerがよく 使われている印象 同一Container内だけでやり取りできるのが Zenject Signalの特徴 Unityアドカレで詳細を書いたのでそちらもご査収 ください。 http://adarapata.hatenablog.com/entry/2018/12/ 13/041721 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 11

Slide 11 text

購読側 public class UserJoinedSignal { public string Username; } public class Greeter { public void SayHello(UserJoinedSignal userJoinedInfo) { Debug.Log($"Hello{userJoinedInfo.Username}!"); } } 送りたいイベントをclass or structにして、購読側は 受け皿のメソッドを作る 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 12

Slide 12 text

発行側 public class GameInitializer : IInitializable { readonly SignalBus _signalBus; public GameInitializer(SignalBus signalBus) { _signalBus = signalBus; } public void Initialize() { _signalBus.Fire( new UserJoinedSignal() { Username = "Bob" }); } } Containerから SignalBus を受け取り、 Fire で送信する 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 13

Slide 13 text

Installer public class GameInstaller : MonoInstaller { public override void InstallBindings() { SignalBusInstaller.Install(Container); // Signalを定義 Container.DeclareSignal(); Container.Bind().AsSingle(); // Signalが来た時にGreeter.SayHelloに投げる Container.BindSignal() .ToMethod(x => x.SayHello) .FromResolve(); Container.BindInterfacesTo() .AsSingle(); } } SignalをBindする 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 14

Slide 14 text

こんなときに便利そう 不特定多数からのイベントを受け取らなくてはな らないとき Pub/Subで疎結合にしたいけどグローバルにどこか らでもメッセージが来るのは不安というときに なんでもかんでもSignalにするとあちらこちらに飛 び回ってデバッグしにくいのでほどほどに(個人の 感想です) 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 15

Slide 15 text

MemoryPoolMonitor Zenject MemoryPoolの状況を可視化できる そもそもZenject MemoryPoolとは 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 16

Slide 16 text

Zenject MemoryPool Unityでのオブジェクトプールを実現する機能 Containerでインスタンスを管理してくれる PureClass、MonoBehavior両方対応 MonoBehaviorの場合Active/非Activeで対応す るっぽい MemoryPoolは標準機能で、MonitorがOptional 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 17

Slide 17 text

public class Foo { public class Pool : MemoryPool { } } public class Bar { readonly Foo.Pool _fooPool; readonly List _foos = new List(); public Bar(Foo.Pool fooPool) { _fooPool = fooPool; } public void AddFoo() => _foos.Add(_fooPool.Spawn()); public void RemoveFoo() { var foo = _foos[0]; _fooPool.Despawn(foo); _foos.Remove(foo); } } 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 18

Slide 18 text

public class TestInstaller : MonoInstaller { public override void InstallBindings() { Container.Bind().AsSingle(); Container.BindMemoryPool(); } } Factoryと同じ感じで書ける 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 19

Slide 19 text

MonoBehaviorの場合は MonoMemoryPool でOK public class FooBehavior : MonoBehavior { public class Pool : MonoMemoryPool { } } Zenject Factoryと組み合わせることもできる public class Foo : IPoolable { private IMemoryPool _pool; public void OnSpawned(IMemoryPool p1) => _pool = p1; public void OnDespawned() => _pool = null; public class Factory : PlaceholderFactory { } } // Foo.Factory.Create()の裏側でPoolされる Container.BindFactory() .FromPoolableMemoryPool(x => x.WithInitialSize(10)); 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 20

Slide 20 text

Zenject Pool Monitorで現在Poolしている数を 確認できる NumTotal: 現在Poolしている合計数 NumActive: 現在使われている数 Num Inactive: 現在使われていない数 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 21

Slide 21 text

こんなときに便利そう Zenjectに乗っかりつつも、メモリコストを抑えた いとき オブジェクトプールを自分で書くのが面倒な時に Zenject Factoryの恩恵に与れるのがミソ Monitorがあるので把握しやすい でもガリガリチューニングしたいときはそもそも Zenject使わない可能性 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 22

Slide 22 text

Re ection Baking Installerの実行時間を短縮する機能 Inject時のリフレクションがボトルネックになりが ちなので、対象のメソッドやクラスの情報を予め Bakeしておく staticに情報が保持されるので速いっぽい。 裏側では cecil というライブラリが動いてる https://github.com/jbevain/cecil 既存のアセンブリに任意のILを差し込める凄いやつ 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 23

Slide 23 text

[Create] -> [Zenject] -> [Re ection Baking Settings] 設定ファイルが爆誕する 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 24

Slide 24 text

Include Assemblies にBake対象のアセンブリを指定 名前空間のパターンマッチングでもいいらしい(未 検証) エディタ上で確認したいときは Is Enabled In Editor 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 25

Slide 25 text

早くなるの? ZEN_INTERNAL_PROFILING で確認してみる ↑を入れるとSceneContext.Awakeの実行ログが吐か れて便利 公式のSample SpaceFighter で確認してみる 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 26

Slide 26 text

Before After 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 27

Slide 27 text

サンプルプロジェクト規模だとわから なかった 公式だと起動時間が最大45%短縮したらしい 俺たちのZenjectを信じろ 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 28

Slide 28 text

こんなときに便利そう Installer部分がボトルネックになっているとき 検証は簡単なのでとりあえずやってみるのは良さ そう ファイルサイズが少し増えるはずなので注意 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 29

Slide 29 text

まとめ Optional Extrasは色々面白いのがある ZEN_INTERNAL_PROFILING で数値見ていこう 日本語記事は少ないのでみんなで書こう 流行って! 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018

Slide 30

Slide 30 text

おわり 2018/12/15 【年末だよ】Unity お・と・なのLT大会 2018