Искать

3 крутых способа разработки игр с помощью скриптуемых объектов

Last updated: December 2018

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

Послушайте советы от Райана Хиппла, ведущего инженера в Schell Games. Он знает, как использовать скриптуемых объектов для создания архитектуры игр. Посмотрите, как Райан рассказывает о программируемых объектах сюда на Unite. Также рекомендуем посмотреть доклад инженера Unity Ричарда Файна на замечательное введение в скриптумеые объекты. Спасибо Райан!

Вкратце: Что такое скриптуемые объекты?

ScriptableObject - это класс, который позволяет хранить большое количество передаваемой информации независимо от образцов скрипта. Использование скриптуемых объектов облегчает управление изменениями и отладкой. Вы можете встроить уровень гибкой коммуникации между различными системами в своей игре, так что в целом она становится более легко управляемой к изменениям и адаптации по мере вашего продвижения, а также к повторному использованию компонентов.

Три кита проектирования игр

Поддерживайте модульность...

  • Избегайте создания систем, непосредственно зависящих друг от друга. Например, инвентарная система должна иметь возможность соединяться с другими системами в вашей игре, но не стоит создавать жестких связей между ними, поскольку будет трудно пересобрать системы, поменяв конфигурации и взаимоотношения между ними.
  • Создавайте сцены с чистого листа: избегайте существования транзитных данных между сценами. Всякий раз, когда вы вызываете сцену, должен происходить полный разрыв с предыдущей сценой и загрузка с нуля. Это позволяет вам иметь сцены с уникальным поведением, отсутствовавшим в других сценах, и без всяких заморочек.
  • Настраивайте префабы так, чтобы они могли работать сами по себе. Насколько это возможно, каждый префаб, который вы переносите в сцену, должен иметь свою функциональность, содержащуюся в нем самом. Это во многом поможет при контроле исходного кода в больших группах, когда сцены представляют собой перечень префабов, и ваши префабы содержат индивидуальную функциональность. Тогда большинство возвратов происходит на уровне префабов, что приводит к меньшим конфликтам в игре.
  • Фокусируйте каждый компонент на решении одной проблемы. Это облегчит сбор компонентов вместе с целью создания нечто нового.

...редактируемость

  • Делайте свои игры по возможности управляемыми потоками данных: когда ваши игровые системы подобны машинам, обрабатывающим данные как инструкции, вы можете вносить изменения в игру, даже когда она запущена и работает, более эффективно.
  • Если ваши системы максимально модульные и основанные на компонентах, то их легче редактировать любым членам вашей команды, включая художников и дизайнеров. Если дизайнеры могут сводить вместе различные части игры, не спрашивая обо всех деталях, в большой степени благодаря внедрению единичных компонентов, делающих только одно, тогда они имеют возможность комбинировать такие компоненты другими способами для создания нового геймплея/механики. Райан отметил, что некоторые из самых крутых "фич" были найдены в ходе такого процесса, названного им "развивающимся дизайном".
  • Очень важно,чтобы ваша команда имела возможность вносить изменения в игру во время ее выполнения. Чем больше вы можете менять в своей игре во время ее выполнения, тем лучше вы можете балансировать ее, и, если вы можете сохранять состояние времени выполнения, как это делается в скриптуемых объектах, это будет совсем замечательно.

...и возможности отладки

Этот "кит" скорее является следствием первых двух. Чем более модульна ваша игра, тем легче тестировать любую ее часть. Чем более редактируема ваша игра, то есть, чем больше в ней частей, имеющих свое окно Инспектора, тем легче ее отлаживать. Сделайте так, что вы можете просматривать состояние отладки в Инспекторе, и никогда не считайте что-то сделанным, пока вы не имеете плана отладки этого.

Что можно делать с помощью скриптовых объектов

Переменные

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

Плавающая переменная для программируемых объектов Unity

Благодаря этому приему любой член вашей команды, независимо от своих технических навыков, может определить новую игровую переменную, создав новый ассет FloatVariable. Любой класс MonoBehaviour или ScriptableObject может использовать FloatVariable вместо public float, чтобы ссылаться на это новое общее значение.

Еще лучше то, что если один MonoBehaviour изменяет значение переменной FloatVariable, остальные MonoBehaviour увидят это изменение. Это создает своеобразный уровень общения между системами, не требующий ссылок друг на друга.

Рассмотрим этот прием на примере здоровья игрока. В игре с одним локальным игроком здоровье игрока может выражаться переменной типа FloatVariable с именем PlayerHP. Когда игрок получает урон, он вычитается из PlayerHP, а когда игрок лечится, PlayerHP увеличивается на соответствующую величину.

Теперь представим, что в сцене есть шкала здоровья игрока. Эта шкала отслеживает значение переменной PlayerHP и меняется соответствующим образом. Без переработки программного кода можно легко сделать так, чтобы эта шкала отражала нечто другое, например значение переменной PlayerMP. Шкала здоровья не знает ничего об игроке в сцене, она просто считывает значение указанной ей переменной.

Программируемый объект Unity и смерть игрока

Когда настройка закончена, будет несложно добавить несколько элементов для отслеживания здоровья игрока (PlayerHP). Музыкальная система может изменяться по мере снижения показателя, враги могут изменять стиль атаки, если знают, что игрок ослаблен, эффекты на экране могут подчеркивать опасность следующей атаки. Ключевым моментом является то, что скрипт игрока не отправляет сообщения в эти системы, и им не нужно знать об игровом объекте игрока. Также вы можете войти в окно «Инспектор», когда игра запущена, и изменить значение PlayerHP, чтобы проверить, как все работает.

При редактировании Value для FloatVariable, стоит скопировать свои данные в переменную времени выполнения, чтобы не менять значение, хранящееся на диске для ScriptableObject. Если вы сделаете это, классы MonoBehaviour должны иметь доступ к RuntimeValue, чтобы предупредить изменение InitialValue, сохраненного на диск.

Плавающая переменная для программируемых объектов Unity

Мероприятия

Одной из моих любимых возможностей в связи со скриптовыми объектами является система событий. Архитектуры события помогают делать код более модульным, отправляя сообщения между системами, не знающих непосредственно друг о друге. Это позволяет им реагировать на изменения в состоянии, не занимаясь постоянным мониторингом.

Эта система событий состоит из двух частей: GameEvent ScriptableObject и GameEventListener MonoBehaviour. Дизайнеры могут создавать любое количество игровых событий GameEvents, которые можно использовать для отправки сообщений. Слушатель GameEventListener ожидает появления конкретного события GameEvent и отвечает запуском события UnityEvent (это не настоящее событие, а скорее вызов сериализованной функции).

Программируемый объект Unity и слушатель игрового события

Программируемый объект Unity и слушатель игрового события

Программируемый объект Unity и слушатель игрового события

Примером такого подхода может служить обработка смерти игрока в игре. В этом месте игры должно меняться исполнение многих систем, и может быть трудно определить, где запрограммировать всю логику. Должен ли скрипт игрока вызывать интерфейс конца игры, смену музыки? Должны ли враги постоянно проверять, жив ли еще игрок? Система событий дает возможность избегать проблематичных зависимостей такого рода.

Когда игрок умирает, скрипт игрока вызывает появление события OnPlayerDied. Скрипту игрока не нужно знать, какие системы заботит появление этого события, поскольку происходит широковещательная рассылка. Game Over UI прислушивается к событию OnPlayerDied и начинает соответствующую анимацию, скрипт камеры может прислушаться к событию и начать затенение камеры, а музыкальная система может отреагировать сменой музыки. Кроме того, каждый враг может прислушиваться к OnPlayerDied, реагируя на это событие победной анимацией или сменой своего состояния.

В такой схеме невероятно легко добавлять новые отклики на смерть игрока. Кроме того, легко тестировать отклик на смерть игрока, вызывая Raise по событию из тестируемого участка программного кода или кнопкой из инспектора.

Программируемый объект Unity и смерть игрока

Система событий, которую я построил в Schell Games, выросла в нечто гораздо более сложное и имеет возможности передавать данные и автоматические генерировать типы. Я не могу разъяснить здесь все детали, но этот пример явился отправной точкой используемой сейчас системы.

Системы

Скриптуемые объекты не обязательно должны оперировать лишь с данными. Возьмите любую систему, внедренную вами в MonoBehaviour, и посмотрите, нельзя ли перенести ее в ScriptableObject. Вместо того, чтобы иметь InventoryManager на DontDestroyOnLoad MonoBehaviour, попробуйте поместить на ScriptableObject.

Так как он не привязан к сцене, у него нет компонента Transform, как и функции Update, но он будет поддерживать свое состояние между загрузками сцены без особой инициализации. Вместо отдельного файла, воспользуйтесь открытой ссылкой на объект системы снаряжения, когда для доступа в снаряжение нужен скрипт. Так смена снаряжения на тестовое или обучающее будет выполняться проще, чем при использовании отдельного файла.

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

Дополнительные ресурсы

Мы очень хотим знать, нравится ли вам наш контент.

Да, хочу больше Нет, могло быть и лучше

Unity Buffbot поможет вам

Подпишитесь, чтобы получать еженедельные сводки по техническим и креативным "ноу-хау" от экспертов Unity.

Subscribe
Согласен

Мы используем cookie-файлы, чтобы вам было удобнее работать с нашим веб-сайтом. Подробные сведения смотрите на странице политики обработки cookie-файлов.