ZenjectとEasySaveの組み合わせについて

EasySaveでGameObjectクラスを保存するとそれにアタッチされているクラスも一緒に保存してくれます。

そして復元時にアタッチされていたクラスも復元されます。


これがすごく便利!


しかし、アタッチされているクラスにInjectされる変数があった時を考えます。

// このクラスがあるクラスにアタッチされて保存、復元される
public class Hoge : MonoBehaviour
{
    [Inject] private IHolder _holder;

    [E3Seializable] private int _num;
}

こんな感じで。


アタッチされているクラスがLoadされて復元されたとき、Hogeも復元されますがこのとき、Injectされている IHolder のインスタンスは null のままです。

通常であればアタッチするときに

_diContainer.InstantiateComponent<Hoge>(gameObject);

とすることで、AddComponent + Injectが解決されますがEasySaveによる復元はZenjectのことなど知らないので[Inject]変数はnullのまま。


シーン全体を保存、復元したら問題ないと思いますがそんな激重なことはしてられないのでどうにか解決策はないか考え「生成後にInjectしてくれるメソッドがあれば解決しそう,,,」と思ってたら

ありました。


// 指定したgameObjectに対してInjectし直す
_diContainer.InjectGameObject(hoge.gameObject);

InjectGameObject メソッドに対してgameObjectを引き渡すと そのGameObject全体をInjectしてくれます


つまり

「EasySave3であるGameObject全体を復元」→「InjectGameObjectでInjectしてもらう」

これで無事にZenjectの機能も使えるようになりました、


注意点

生成後にInjectするのでAwakeメソッドの中でInjectされる変数の使用が出来ません

InjectGameObjectの挙動について

GameObjectを指定するということは、そのGameObjectにアタッチされているすべてのスクリプトに対してInjectが走ります。

つまり、一つ一つアタッチされているスクリプト内でこのメソッドを呼び出す必要はありません。


一度メソッド呼び出してしまえば↓ 画像のようにアタッチされているスクリプト全体にインジェクトされています

f:id:toshizabeth:20210618094035p:plain

おわり

EasySaveなり他のライブラリなど生成時のInjectが受けられないときに使える