Выпуск от 13 декабря 2017г.
Сегодня в выпуске «Истребителей багов» Марк Эйбент возьмется за решение проблемы, затрагивающей конфликтующие интерфейсы (UI) на многоместных транспортных средствах. Посмотрите эту серию, чтобы узнать, как он раздавит этот конкретный баг.
Марк начинает на небольшой карте для тестирования мультиплеера в своем любимом корабле Cutlass. Также у него на борту есть второй игрок, точнее второй персонаж под его собственным управлением. Один персонаж пилотирует корабль, а второй в это время находится у того за спиной. Как вы можете видеть, UI пилота пока в порядке (видно, как игровые объекты вызывают появление ошибок движка, но это не относится к сегодняшнему багу). Теперь второй персонаж убегает и садится в турель. Он вращает турель, стреляет; UI при этом работает. Но когда персонаж решает выйти из турели и обесточивает ее, то вместе с ее интерфейсом также пропадает и UI у пилота корабля. Это совсем не круто, ведь в многоместных кораблях люди будут садиться за свои рабочие места и вставать с них, и вы не захотите, чтобы при этом у вас произвольно отключались экраны с интерфейсом.
Что же происходит? Когда-то давно, когда Марк и сотоварищи писали фреймворк для предметов, они забыли учесть несколько вещей. По сути, в игре есть контроллеры, предметы и игроки. Игрок берет управление контроллером, который затем берет управление предметом. Если взять в пример стрельбу, игрок управляет контроллером вооружения, который в свою очередь управляет орудиями.
В случае с UI на экранах игрок берет управление своей приборной панелью, а приборная панель просматривает все остальные предметы, чтобы иметь возможность быстро отобразить информацию о них на экранах. К сожалению, когда у вас две приборные панели, они начинают мешать друг другу, потому что интерфейс для включения и выключения различных вещей на самом деле управляется контроллерами, а не панелями. Скажем, у нас есть контроллер энергии, который управляет питанием, и есть две приборные панели, каждая из которых хочет наблюдать за состоянием питания. К счастью, каждый раз, когда приборная панель решает включить или выключить какой-то объект, она в действительности отправляет запрос контроллеру, где просит его сделать это. Это значит, что если панель была обесточена, или если пользователь выключил все экраны, она отправит запрос контроллеру энергии, чтобы тот отключил UI, потому что именно контроллер управляет интерфейсами. Для решения проблемы нужно сделать так, чтобы этот аспект управлялся приборными панелями, а не контроллером, потому что панели хотят лишь получать информацию о контроллере энергии. Им не важен тот факт, что контроллер включает или выключает UI. В общем, нужно разделить эти участки кода.
Марк показывает базовый класс контроллеров. Здесь собраны контроллеры энергии, оружия и всего остального. Здесь есть компонент, отвечающий за обновление состояний UI. Он переключается каждый раз при включении или при прикреплении, но нам как раз не нужно, чтобы он влиял на UI. Воспользовавшись волшебной кнопкой Delete, Марк исправляет ситуацию. Он удаляет там все. У компонента больше нет контроля над интерфейсом, и теперь надо передать управление UI приборной панели.
Нам не нужны контроллеры для включения предметов – мы должны делать это сами. Поэтому Марк вставляет в функцию обновления состояния питания экрана заранее подготовленный фрагмент кода. Этот код соберет информацию обо всех активных экранах на приборной панели и переключит состояние питания, основываясь на полученной от панели информации. Теперь UI управляется приборной панелью. Если второй пилот выключит свою приборную панель, нам нужно будет убедиться, что отключатся только его экраны – именно это и делает написанный код.
Далее нужно разобраться с ошибками той части кода, где происходит создание экранов. Если во время создания экрана приборная панель уже включена, нужно убедиться, что эти новые экраны также будут включены. После внесения определенных правок и добавления необходимых проверок можно скомпилировать код и посмотреть на результат. Теперь у приборной панели есть свое собственное состояние активности. Нам нужно, чтобы она управляла только интерфейсом на экранах, но не самими контроллерами. Чтобы проще понять ситуацию, можно провести аналогию с ПК с тремя мониторами. Если вы включаете или выключаете один из мониторов, вы ожидаете, что это действие не повлияет на монитор вашего соседа.
После компиляции мы вернулись в Cutlass на тестовый уровень. Пилот все также управляет кораблем, а второй пилот стоит у него за спиной. Интерфейс пилота работает. Второй игрок, как и в прошлый раз, идет и садится за турель. Затем он выключает питание турели, но интерфейс пилота продолжает работать. Все шикарно.
Итак, резюмируем содержание выпуска. У нас был один мультиплеерный баг, похожий на игру в Nintendo 64 за большим телевизором в режиме split-screen: когда вы выключаете телевизор – все выключается. Не очень хорошо, особенно когда каждый игрок видит на экране какую-то свою информацию. Благодаря внесенным исправлениям приборные панели теперь отделены друг от друга. Вы можете включать или выключать экраны на одной панели, и это никак не скажется на экранах на соседней панели. Теперь парень за турелью не вызовет хаос по всему кораблю, когда обесточит свой экран.
Надеюсь, вам понравилось, и до скорой встречи.
Перевод: H_Rush