Zenject ломает сборку под WebGL

Дата публикации: 2023-02-06
Просмотры: 1414

Представьте, что вы делаете проект на Unity3D.
И вот вы решаете облегчить себе жизнь и использовать DI контейнер.
Для этого обычно все используют Zenject.
Но что делать если Zenject ломает функциональность на сборках под WebGL.

Zenject ломает сборку под WebGL

Введение

Zenject — контейнер внедрения зависимостей с открытым исходным кодом.
Zenject можно применять и для С# приложений, разработанных без Unity3D.
Этот контейнер довольно популярен среди Unity разработчиков.

Zenject довольно прост и удобен в использовании. Но с ним надо быть очень осторожным и внимательным. Так как в случае ошибок, найти причину бывает не просто.

Проблема

В Zenject есть два типа контекста.
Scene Context - создается для каждой сцены отдельно.
Project Context - создается автоматически для всего проекта. Существует в единственном экземпляре.

Предположим вы хотите чтобы какие объекты были в игре в единственном экземпляре и не удалялись при смене сцен.
Это может понадобится, например, для фоновой музыки или общих UI элементов.
Для этого логичнее всего сделать префаб с необходимым объектом и потом его создать в проекте примерно следующим кодом.
Этот код должен быть привязан к Project Context Zenject.

namespace App.Installers
{
    public class AppInstaller : MonoInstaller
    {
        [SerializeField] private MainController mainController;
        [SerializeField] private MusicController musicController;

        public override void InstallBindings()
        {
            BindMainController();
            BindMusicController();
        }

        private void BindMainController()
        {
            Container.Bind<MainController>()
                .FromComponentInNewPrefab(mainController)
                .WithGameObjectName("MainCanvas")
                .AsSingle()
                .NonLazy();
        }

        private void BindMusicController()
        {
            Container.Bind<MusicController>()
                .FromComponentInNewPrefab(musicController)
                .WithGameObjectName("Music")
                .AsSingle()
                .NonLazy();
        }
    }
}

После этого на сцене появятся объекты в блоке DontDestroyOnLoad

image

Все вроде хорошо и в редакторе все будет работать отлично.
Но при сборке под WebGL ваше приложение будет работать не так как вы задумывали.
Фоновая музыка играть не будет. Общие окна с ошибками и тд отображаться не будут.

Поиск в интернете результата не дал.
Но с помощью отладки я понял что наши неубиваемые объекты при смене сцен все равно удаляются.

Решение

Так что же делать чтобы объекты не удалялись со сцен.

Можно пойти простым способом добавить на эти объекты скрипты и прописать там следующий код.

namespace App.Controllers
{
    public class MusicController : MonoBehaviour
    {
        private void Awake()
        {
            DontDestroyOnLoad(gameObject);
        }
    }
}

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

Как оказалось решением является установка одного флага в настройке Project Context Zenject.
Это свойство называетяс Parent New Objects Under Context

image

Проставив этот флаг, наши объекты немного поменяют иерархию и она будет выглядеть следующим образом.

image

После этого наша сборка под WebGL начинает работать как задумано.
Вот такое простое, но не очевидное решение.

Предыдущая статья:

Вышла новая версия PHPUnit 10.0

Следующая статья:

Вышла новая версия Laravel 10.0
Поделиться статьей:

Комментарии:

Авторизуйтесь, для того, чтобы оставить комментарий. Войти на сайт
Подписка на новости
Узнавайте о новых статьях первыми.
Профиль