unity-game-enginedependency-injectionzenject

Chose GameObject from SettingCollection


I'm using Zenject framework and I want instansiate gameObject for class created by factory. For this I'm using something like this in GameInstaller

Container.BindFactory<int,int,Hex, Hex.Factory().
    FromComponentInNewPrefab(_settings.PlainHexPrefab[0]).
    WithGameObjectName("Hex").
    UnderTransformGroup("Zenject");`

It's work fine, but in my case in _settings.PlainHexPrefab I have collection GameObjects and I need choose one of them dependency by properties from Hex object. How could I do it?


Solution

  • Here's three ways that might work for you:

    1. FromMethod

      public class Hex : MonoBehaviour
      {
          public class Factory : PlaceholderFactory<int, int, Hex>
          {
          }
      }
      
      public class TestInstaller : MonoInstaller<TestInstaller>
      {
          public GameObject[] HexPrefabs;
      
          public override void InstallBindings()
          {
              Container.BindFactory<int, int, Hex, Hex.Factory>().FromMethod(CreateHex);
          }
      
          Hex CreateHex(DiContainer _, int p1, int p2)
          {
              var prefab = HexPrefabs[Random.RandomRange(0, HexPrefabs.Count() -1)];
              return Container.InstantiatePrefabForComponent<Hex>(prefab);
          }
      }
      
    2. Custom Factory

      public class HexFactory : IFactory<int, int, Hex>
      {
          readonly DiContainer _container;
          readonly GameObject[] _prefabs;
      
          public HexFactory(
              GameObject[] prefabs,
              DiContainer container)
          {
              _container = container;
              _prefabs = prefabs;
          }
      
          public Hex Create(int p1, int p2)
          {
              var prefab = _prefabs[Random.RandomRange(0, _prefabs.Count() -1)];
              return _container.InstantiatePrefabForComponent<Hex>(prefab);
          }
      }
      
      public class TestInstaller : MonoInstaller<TestInstaller>
      {
          public GameObject[] HexPrefabs;
      
          public override void InstallBindings()
          {
              Container.BindFactory<int, int, Hex, Hex.Factory>()
                  .FromIFactory(b => b.To<HexFactory>().AsSingle().WithArguments(HexPrefabs));
          }
      }
      
    3. Sub factories in custom factory. This also has the advantage that each prefab factory should be 'validated'

      public class CustomHexFactory : IFactory<int, Hex>
      {
          readonly List<Hex.Factory> _subFactories;
      
          public CustomHexFactory(List<Hex.Factory> subFactories)
          {
              _subFactories = subFactories;
          }
      
          public Hex Create(int p1)
          {
              return _subFactories[Random.RandomRange(0, _subFactories.Count() -1)].Create(p1);
          }
      }
      
      public class TestInstaller : MonoInstaller<TestInstaller>
      {
          public GameObject[] HexPrefabs;
      
          public override void InstallBindings()
          {
              foreach (var prefab in HexPrefabs)
              {
                  Container.BindFactory<int, Hex, Hex.Factory>().FromComponentInNewPrefab(prefab)
                      .WhenInjectedInto<CustomHexFactory>();
              }
      
              Container.BindFactory<int, Hex, Hex.Factory>().FromFactory<CustomHexFactory>();
          }
      }