LoginSignup
34
31

More than 5 years have passed since last update.

【Unity】Zenjectをちょっと触ってみた

Last updated at Posted at 2016-10-11

はじめに

Zenjectがイイらしいという情報を見かけたので軽く触ってみました。

環境

Unityのバージョンは5.3.5f1, OSはWindows10です

Zenject?

Zenject is a lightweight dependency injection framework built specifically to target Unity 3D

DI (Dependency Injection, 依存性の注入) を扱うためのフレームワークだそうです。

1. とりあえず使ってみる

1. Zenjectのダウンロード

以下URLからダウンロードしてUnityProjectに入れます。
https://github.com/modesttree/Zenject/releases

AssetStoreからもダウンロードできます


筆者は Zenject-WithSampleGames.v4.5.unitypackage をダウンロードしました。

2. Hello World

公式のHelloWorldを参考に実際に動かしていきます。

  1. Hierarchyで右クリックして、Zenject -> Scene Context を選択して、SceneContextを作成 image



2. 以下のスクリプトを作成して好きなGameObjectにアタッチ。

TestInstaller.cs
using Zenject;
using UnityEngine;
using System.Collections;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.BindInstance("Hello World!");
        Container.Bind<TestRunner>().NonLazy();
    }
}

public class TestRunner
{
    public TestRunner(string message)
    {
        Debug.Log(message);
    }
}

3.SceneContextにTestInstaller付きのオブジェクトをアタッチ
image

4.Validate ( Ctrl + Shift + V )するとConsoleに以下のようなメッセージが表示されます.
image

あまり理解できていないのですが、InstallBindings()内にてクラス間の依存関係を定義しているみたいです。

2. サンプルをちょっと覗いてみた

同梱のサンプルゲームに使われているコードがどのような意味を持つのか表にまとめてみました。
各コードはInstallBindings()の中で呼んでいるものとしています。

コード 意味 エラー例  備考
Container.Bind<IF>().To<A>() インターフェースIFをクラスAが継承していることを保証する? AIFを継承していないとエラー IFの代わりにクラスBを入れても動くみたいです
Container.BindFactory<A, B>() クラスBFactory<A>に変換可能であることを保証する? BFactory<A>へ変換できないとエラー Factory<>はZenjectで提供されているクラス
Container.BindInstance<int>(x).AsSingle() int型の変数xが変わらないことを保証する? 1回目のBindInstance呼び出しと2回目のBindInstance呼び出しで異なるint値が渡されるとエラー
Container.BindAllInterfaces<A>().To<B>() クラスAが継承している全てのインターフェースをクラスBが継承していることを保証する? Aが継承するインターフェースの中にをBが継承していないものがあるとエラー

3. Injectを使ってみた

Injectもちょっと触ってみました。 DIを行うためのものらしいです

引数なしメソッドを呼ぶ

シーンを再生するとA()メソッドが実行されます.

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<Hoge>().NonLazy();

    }
}

public class Hoge
{
    [Inject]
    void A()
    {
        Debug.Log("A");
    }
}

実行結果
image

引数ありメソッドを呼ぶ

WithArgumentsを使うとメソッドに引数を渡せるみたいです。

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<Hoge>().WithArguments(810, 114514).NonLazy();
    }
}

public class Hoge
{
    [Inject]
    void A(int x, int y)
    {
        Debug.Log("A : x = " + x + ", y = " + y);
    }
}

実行結果
image

4. ITickableを使ってみた

ITickableを使うことで毎フレーム処理を実行するクラスを作ることができるらしいです。

実際に使ってみる

シーンを再生するとTick()メソッドが毎フレーム実行されます

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<ITickable>().To<A>().AsSingle();
    }
}

class A : ITickable
{
    public void Tick()
    {
        Debug.Log("Tick");
    }
}

シーンを再生すると以下のようなLogが出力されます。
image

5. IInitializableを使ってみた

開始時にInitialize()メソッドを実行させるためのインターフェースらしいです

実際に使ってみる

シーンを再生するとInitialize()メソッドが1度実行されます

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<IInitializable>().To<A>();
    }
}

class A : IInitializable
{
    public void Initialize()
    {
        Debug.Log("Initialize");
    }
}

IInitializableをInjectで代用する

以下のように書くことでも同様のことができるみたいです

TestInstaller.cs
using UnityEngine;
using Zenject;

public class TestInstaller : MonoInstaller
{
    public override void InstallBindings()
    {
        Container.Bind<A>().NonLazy();
    }
}

class A
{
    [Inject]
    public void Initialize()
    {
        Debug.Log("Initialize");
    }
}

参考URL

GitHub - modesttree/Zenject
https://github.com/modesttree/zenject

アセットストア - Zenject Dependency Injection IOC
https://www.assetstore.unity3d.com/jp/#!/content/17758

34
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
34
31