Создание случайных или выбранных сборных конструкций с помощью субконтейнера через фабрику или пул - PullRequest
1 голос
/ 10 ноября 2019

У меня есть набор префабов, и я хочу иметь возможность создавать произвольно выбранные префабы через Zenject Factory и выполнять их привязки в своих субконтейнерах.

То же самое, что и в этом примере кода из документации Zenject, но для случайно выбранных префабов. https://github.com/modesttree/Zenject/blob/master/Documentation/SubContainers.md#using-game-object-contexts-no-monobehaviours

using UnityEngine;
using Zenject;

public class GameInstaller : MonoInstaller
{
    [SerializeField]
    GameObject ShipPrefab;

    public override void InstallBindings()
    {
        Container.BindInterfacesTo<GameRunner>().AsSingle();

        Container.BindFactory<float, ShipFacade, ShipFacade.Factory>()
            .FromSubContainerResolve().ByNewPrefabInstaller<ShipInstaller>(ShipPrefab);
    }
}

Мне удалось частично заставить его работать с

[SerializeField] private GameObject[] ships;

...

Container.BindFactory<float, ShipFacade, ShipFacade.Factory>()
            .FromSubContainerResolve().ByNewGameObjectMethod(SpawnShip);

...

private void SpawnShip(DiContainer container, float speed)
{
    container.Bind<ShipFacade>().AsSingle();
    container.Bind<Transform>().FromComponentOnRoot();
    var shipPrefab = ships[Random.Range(0, ships.Length)];
    var ship = container.InstantiatePrefab(shipPrefab);
    container.Bind<ShipHealthHandler>().FromNewComponentOn(ship).WhenInjectedInto<ShipFacade>();
    container.BindInstance(speed).WhenInjectedInto<ShipInputHandler>();
}

Но это неудобно, и в этом случае я предполагаю, что не использую преимущество субконтейнера,А также префабы появляются в пустом GameObject. Чего я хочу достичь, так это возможности использовать ShipInstaller для привязки подконтейнера.

1 Ответ

1 голос
/ 10 ноября 2019

Вы правы, на самом деле не было очень элегантного способа динамического выбора префаба субконтейнера.

Я потратил некоторое время, чтобы сделать это лучше сегодня с этим коммитом ,Если вы используете последнюю версию Extenject , то теперь вы можете делать такие вещи:

public class QuxInstaller : Installer {
    float _speed;

    public QuxInstaller(float speed) {
        _speed = speed;
    }

    public override void InstallBindings() {
        Container.BindInstance(_speed);
        Container.Bind<QuxFacade>().AsSingle();
    }
}

public class CubeInstaller : MonoInstaller
{
    public List<GameObject> QuxPrefabs;

    public override void InstallBindings()
    {
        Container.BindFactory<float, QuxFacade, QuxFacade.Factory>()
            .FromSubContainerResolve().ByNewPrefabInstaller<QuxInstaller>(ChooseQuxPrefab);
    }

    UnityEngine.Object ChooseQuxPrefab(InjectContext _) {
        return QuxPrefabs[Random.Range(0, QuxPrefabs.Count)];
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...