概要
疎結合なクラス設計で開発する際に非常に便利なZenject/Extenjectですが、
扱いの難しさ故に、ちょっとしたことでハマってしまいます。
今回は、動的に生成されたGameObjectがInjectされない問題とその解決策を記載していきます。
Prefabを動的生成する
以下のようなPrefabがあります(以下「プレイヤーPrefab」と表記)。
プレイヤーPrefabにはPlayer.csがアタッチされています。
// ゲームステータスを管理するマネージャ
[Inject] GameManager manager;
void Start()
{
// ゲームステータスがGOなら処理を行う
if(manager.GetGameState == "GO"){
// 好きな処理を書く
}
}
そしてScene内には位置情報だけのPlayerSpawnerオブジェクトがあり、PlayerSpawner.csがアタッチされています。
プレイヤーPrefabはHierarchyには設置せず、PlayerSpawner.csによって動的生成される仕様とします。
[SerializeField] GameObject playerPrefab;
void Start()
{
// プレイヤーPrefabを動的生成する
Instantiate(playerPrefab, new Vector3(0, 0, 0), Quaternion.identity);
}
以上の条件で実行してみると、Player.csにNullReferenceExceptionのエラーが出ます。
エラーの原因はアタッチ先のプレイヤーPrefabが、PlayerSpawnerから動的生成されたことによりInjectされず、managerがnullになってしまうからですね。
解決策
とても簡単で、ZenAutoInjectorをプレイヤーPrefabにアタッチすればOKです。
DI Containerを直接使用し、InstantiatePrefabを行うことでも解決できますが、無駄にコードを増やさずに済むのでZenAutoInjectorを使用するのがおすすめです。