Давайте посмотрим, как делать внутриигровые скриншоты, чтобы увековечить свои дикие приключения!
За последние несколько лет появилось довольно много больших видеоигр, которые предлагали нам безумно хорошие истории, невероятную графику и несколько странные, но забавные функции. Среди этих неожиданных дополнений фоторежим кажется довольно популярным.
Например, хотя события Marvel's Spider-Man и Shadow of Mordor происходят в совершенно разных контекстах, обе игры предлагают изысканный и увлекательный режим изображения, который замораживает действие и позволяют сделать снимок в середине сцены действия.
Что, если бы вы могли делать это и в своих играх на Unity? Сложно реализовать? Спойлер: не совсем так! :)
Итак, сегодня мы увидим:
- 🛠 как настроить фоторежим
- 🔍 как войти и выйти из этого режима с базовым интерфейсом
- 📷 как сделать скриншот и сохранить его на диск
Вы готовы? Тогда вперед!
🛠 Настройка нашего фоторежима
Хорошо, прежде чем мы углубимся в кодирование, давайте быстро обсудим, каким будет наш процесс захвата и сохранения скриншотов в игре.
Важно отметить, что когда камера показывает изображение на вашем экране, на самом деле это происходит только потому, что вы сказали ей преобразовать 3D-сцену в 2D-изображение, а затем вставить это изображение на весь текущий дисплей. Но вы вполне можете попросить его выполнить рендеринг, а затем использовать содержимое этого 2D-изображения каким-то другим способом…
… например, в нашем случае можно было попросить просто сохранить изображение куда-нибудь на диск! :)
Допустим, у меня есть основная камера в моей сцене Unity, которая отображает базовую демо-сцену, и простой контроллер FPS для моего персонажа (это взято непосредственно из базового стартового пакета Unity для FPS, доступного бесплатно здесь):
Демонстрационный контроллер позволяет мне перемещаться с помощью клавиатуры и использовать мышь для вращения камеры, поэтому мы будем считать, что вся эта часть «игровой логики» уже позаботилась.
Здесь мы хотим иметь возможность нажать какую-нибудь клавишу, например <P>
(для «изображения»), чтобы войти в фоторежим. В этом режиме камера будет заблокирована в текущем положении, и у нас будет две кнопки, чтобы либо сделать снимок экрана (и выйти из режима фото), либо напрямую выйти из режима фото.
Давайте создадим скрипт C# с именем PhotoMode
и добавим его в префаб нашего плеера: это игровой объект с именем «PlayerCapsule» в демо-сцене. Если вы откроете его в IDE, вы увидите, что на данный момент он содержит класс MonoBehaviour
по умолчанию, который Unity автоматически генерирует для любого нового скрипта:
Для начала давайте изменим нашу функцию Update()
, чтобы она проверяла наш ввод с клавиши <P>
. Если мы действительно нажимаем эту клавишу, то мы хотим войти в фоторежим с помощью функции _EnterPhotoMode()
:
Примечание. В стартовых пакетах Unity используется новая система ввода. Если вы не знакомы с ним, загляните в документацию, чтобы понять, как получать нажатия клавиш, или перейдите дальше и определите действия.
Теперь, чтобы заморозить камеру, мы собираемся сделать две вещи:
- один, мы полностью отключим скрипт контроллера FPS. Это не даст нам ни двигать игрока, ни камеру и имитировать эту «заморозку».
- во-вторых, мы установим глобальную переменную
Time.timeScale
в0
. Если вы точно не знаете, что делает эта переменная, не стесняйтесь взглянуть на эту недавнюю статью, которую я написал на эту тему :)
Чтобы иметь возможность отключить наш скрипт контроллера, нам сначала нужно получить ссылку на него. Поскольку он находится на том же игровом объекте, что и наш скрипт PhotoMode
, для этого мы можем использовать встроенный GetComponent()
. А учитывая, что эта ссылка не изменится на протяжении всей игры, мы можем получить ее один раз в начале в хуке Start()
, а затем повторно использовать позже в коде.
Кроме того, поскольку сценарии стартового пакета находятся в пространстве имен StarterAssets
, нам нужно сначала импортировать его с ключевым словом using
:
Если вы попробуете это сделать, вы увидите, что как только вы нажмете клавишу <P>
, экран зависнет, как и ожидалось! За исключением того, что на данный момент у нас нет возможности выйти из этого режима…
🔍 Добавление пользовательского интерфейса и выход из фоторежима
К счастью, это довольно легко решить :)
Сначала нам нужно добавить две кнопки на Canvas (здесь я поэкспериментировал со спрайтами пользовательского интерфейса из стартового пакета и добавил несколько дополнительных значков):
Затем мы можем подготовить две общедоступные функции в нашем скрипте PhotoMode
для каждой из этих кнопок:
И, наконец, вернувшись в редактор, мы можем перейти к инспектору каждой кнопки и добавить обратный вызов с соответствующей функцией:
Теперь в нашем скрипте PhotoMode
мы собираемся добавить общедоступную ссылку на нашу родительскую панель пользовательского интерфейса «PhotoMode»: это упростит отображение или скрытие всего пользовательского интерфейса одновременно.
Примечание: не забудьте перетащить ссылку в инспектор после перекомпиляции скрипта! :)
И последнее, но не менее важное: поскольку контроллер FPS управляет мышью, по умолчанию он скрывает указатель. Таким образом, несмотря на то, что у нас есть пользовательский интерфейс, на который можно щелкнуть, в настоящее время у нас нет мыши, чтобы навести на него курсор! Чтобы решить эту проблему, нам нужно добавить небольшую строку в наши функции входа/выхода:
Обязательно сначала отключите панель пользовательского интерфейса — затем, если вы запустите игру, вы увидите, что нажатие <P>
вызывает пользовательский интерфейс и останавливает игру, а затем нажатие крестообразной кнопки в правом нижнем углу возвращает к обычному режиму. режим:
📷 Скажи «сыр»!
Хорошо, наконец-то мы здесь: нам нужно разобраться со скриншотом экрана.
Вкратце идея состоит в том, чтобы:
- во-первых, подготовьте временную одноразовую текстуру для рендеринга камерой.
- затем зафиксируйте текущий вид камеры на этой текстуре
- затем получите содержимое текстуры и сохраните его как файл изображения.
- наконец, очистим наши временные переменные, чтобы не загромождать память
Временная текстура может быть создана с помощью переменной RenderTexture
. Чтобы визуализировать нашу камеру в эту текстуру, нам просто нужно назначить нашу текстуру рендеринга в качестве текущей цели для камеры, а затем вызвать функцию, которая легко доступна для ручного рендеринга: Camera.Render()
.
Третий шаг в основном касается передачи и преобразования данных из одного формата в другой — я не буду вдаваться в подробности здесь, но не стесняйтесь просматривать различные темы в сети, в которых обсуждается этот вид преобразования; )
В общем, вот функция, которая будет делать скриншоты:
Во второй половине метода у меня есть несколько строк, посвященных подготовке папки со скриншотами (где-то в моем домашнем каталоге), поэтому мне нужен новый импорт System.IO
вверху. Конечно, вы должны адаптировать этот путь по своему вкусу. Обратите внимание, что скрипт автоматически вычисляет суффикс с нулевым дополнением и увеличивающийся номер для изображений на основе количества файлов, уже присутствующих в данной папке.
В конце концов, очистка в основном сводится к уничтожению нашей текстуры рендеринга и самой текстуры. Также есть небольшая отладка, чтобы убедиться, что все прошло хорошо.
Если я попробую это, тадаа! Я получаю хороший скриншот моего текущего вида :)
Окончательный сценарий
Если вы хотите попробовать это сами, вот окончательный сценарий PhotoMode
C#, который необходимо добавить к игровому объекту «PlayerCapsule»:
Вывод 📸
В этой статье мы увидели, как быстро создать базовый фоторежим для игры на Unity, позволяющий делать внутриигровые снимки и сохранять их на диск.
Но есть еще много улучшений, которые мы могли бы сделать, например, добавить границы, похожие на камеру, возможно, некоторый эффект светового экрана и звук «щелчка»… Сообщите мне в комментариях, хотите ли вы, чтобы я сделал еще одну статью с этими функциями! ;)
Надеюсь, вам понравился урок, и, как обычно, большое спасибо за чтение :)
Чтобы читать больше моего контента и статей многих других замечательных писателей из Medium, рассмотрите возможность стать участником! Ваш членский взнос напрямую поддерживает писателей, которых вы читаете.