Значительную часть атмосферы игры создают звуковые эффекты. Со звуком работать тоже не сложно, достаточно импортировать его форматом Wav 16 и проигрывать с помощью блюпринтов (или кода на С++) в нужном месте. Или поставить компонент звука и включать/выключать его в нужные моменты.
Миксовать и создавать комплексные звуковые эффекты в UE4 тоже можно — опять же, с помощью нодового редактора.
Хорошо, графика уже выглядит прилично. Осталось настроить пользовательский интерфейс (UI).
В Unreal Engine 4 есть специальный редактор виджетов — UMG. Как и всё остальное, он простой и мощный. Можно размещать элементы с якорями, можно создавать блочную вёрстку, встраивать виджеты внутри других виджетов и так далее. Есть куча разных настроек, почти всё можно переделать или анимировать.
С помощью UMG можно создать меню, HUD и другие части пользовательского интерфейса, а настроить работу всего этого можно через те же блюпринты.
В чем проблема UObject?
Проблем в целом нет, ну или я просто не сталкивался с ними. Все, чем раздражает UObject, так это отсутствие различных возможностей, которые по умолчанию доступны в AActor или в компонентах. Вот проблемы, которые я выделил за свою практику:
Большую часть вещей можно легко решить. А вот с некоторыми придется повозиться.
Проект готов, и вполне возможно, что во время работы даже не нужно было открывать другие программы — помимо браузера с документацией и магазина с ассетами. Здорово! Теперь нужно собрать игру под определённую платформу.
UE4 позволяет собрать проект под все популярные платформы, от ПК и консолей до мобильных устройств и даже HTML5. Для ПК хватает одного клика, а вот для остальных платформ может понадобиться дополнительный SDK, инструкции по которому есть в документации.
В Unreal Engine 4 есть ещё много полезных инструментов, мы разобрали только самые основные. В целом, это один из самых привлекательных движков на сегодняшний день — много полезных инструментов и лёгок в освоении.
После выбора шаблона или демо-проекта вы попадёте в редактор. В первый раз здесь можно потеряться — в UE4 огромное количество фичей и кнопочек, а у каждого ассета есть ещё и внутренний редактор для настройки контента. Например, в отдельном редакторе статичных мешей можно сгенерировать низкополигональные модельки, а в редакторе анимаций создать позы или изменить анимацию.
Может показаться, что редактор перегружен функционалом, но в этом и плюс: всё необходимое находится в одном месте. Хотя создавать хороший контент (модели, звуки, текстуры и т.д.) всё равно придётся в сторонних программах.
Зато в UE4 есть инструменты для прототипирования, благодаря которым можно собрать билд игры вообще без использования других программ. Например, с помощью Brush’ей можно смоделировать базовый мир и предметы. А уже потом поменять их на более качественные или оставить как есть, если стилистика проекта позволяет.
Запомните эту картинку
Последняя статья из цикла «Разработка» — работаем с редактором UE4, пишем логику без навыков программирования и начинаем конкурс работ.
Уже две статьи цикла «Разработка» были полностью посвящены Unity и различным туториалам для этого движка. А в этой я расскажу об относительно молодом Unreal Engine 4. Несмотря на то, что оригинальный UE существует уже два десятилетия, новая версия была почти полностью переписана и сильно повлияла на разработку игр в целом. Мы рассмотрим основные плюсы этого движка для начинающих инди-разработчиков с упором на тех, которые никогда раньше не занимались программированием.
Четвертая версия движка вышла в 2014 году и распространялась по подписке за $19 в месяц. Но уже через год Epic Games сделала его бесплатным, после чего Unreal Engine 4 начали использовать не только студии, но и инди-разработчики.
Несмотря на «новизну» UE4, сообщество вокруг движка растёт очень быстро, появляется огромное количество туториалов, документации, ассетов и плагинов.
Всем привет! Меня зовут Александр, я уже более 5 лет работаю с Unreal Engine, и почти все это время — с сетевыми проектами.
Поскольку сетевые проекты отличаются своими требованиями к разработке и производительности, нередко необходимо работать с более простыми объектами, такими как классы UObject, но их функциональность изначально урезана, что может создать сильные рамки. В этой статье я расскажу о том, как активировать различные функции в базовом классе UObject в Unreal Engine 4.
На самом деле, статью я написал скорее как справочник. Большую часть информации крайне сложно найти в документации или сообществе, а тут можно быстро открыть ссылку и скопировать нужный код. Решил заодно поделиться и с вами! Статья ориентирована на тех, кто уже немного знаком с UE4. Будет рассмотрен С++ код, хотя знать его не обязательно. Можете просто следовать инструкциям, если вам нужно то, о чем пойдет речь. Более того, не обязательно копировать все, вы можете вставить код из раздела с нужными свойствами и он должен работать.
На ресурсе доступно
с выполнением тестового заданияс выполнением рабочей задачи / Пакет 5 занятийПакет 10 занятий На бесплатное занятие C++ Unreal Engine разработчикЗанимаюсь разработкой виртуальных миров с 2014 года.
Мое резюме с проектами можно увидеть по ссылке https://igorvasilev.page.link/CV / Пакет 5 занятийПакет 10 занятий На бесплатное занятие с выполнением тестового заданияпройти обучение по программес выполнением рабочей задачи / Пакет 5 занятийПакет 10 занятий На бесплатное занятие Technical Directorпройти обучение по программес выполнением рабочей задачи / Пакет 5 занятийПакет 10 занятий На бесплатное занятие Ведущий разработчикпройти обучение по программес выполнением рабочей задачи / Пакет 5 занятийПакет 10 занятийс выполнением тестового заданияпройти обучение по программес выполнением рабочей задачиНайти ментора для вас?Оставьте заявку — команда Solvery найдет подходящего специалиста за 72 часа!
Чтобы принять участие в конкурсе и собрать наш фидбек, необходимо:
В конкурсе могут участвовать любые прототипы, в том числе сделанные и до цикла «Разработка». Главное, чтобы это был именно прототип, а не часть уже выпущенного проекта или бета-версии перед релизом.
Помните, прототип — это не урезанная версия игры, а только проверка гипотезы. Он может быть сделан и «на кубиках».
Прототип должен показывать, что играть будет интересно. Не стоит делать высокополигональные модели и заказывать музыку у композитора — всё это успеется, сначала нужно понять, что игра того стоит.
На этом цикл заканчивается, а впереди у нас арт и маркетинг. Последняя тема будет полезной, даже если нет многомиллионного бюджета на рекламу.
Прежде чем заменять тестовый контент на собственный, стоит написать механику, то есть кор-геймплей, от которого зависит почти всё в вашей игре. Обычно для этого нужно изучать язык программирования (в Unity, например, это С#, а в UE4 — C++) и писать код, чтобы всё работало как задумано. Но новички могут обойтись и без этого.
В Unreal Engine 4 есть Blueprints — специальный инструмент визуального программирования. Он позволяет строить логику игры с помощью блок-схем из нод. Инструмент достаточно наглядный, простой и интересный в работе. Например, оба скрипта на скриншотах ниже создают мигающую лампочку.
С помощью Blueprints
То же самое, но написанное на С++
С блюпринтами работать намного легче, потому что в них невозможно допустить синтаксическую ошибку — подать неправильный тип данных или забыть поставить нужный знак. Ещё блюпринты защищают от вылетов программы. Например, если в С++ попытаться получить доступ к несуществующему объекту, игра вылетит, а в блюпринтах просто появится ошибка в логе.
Звучит слишком хорошо, чтобы быть правдой. Подвох в том, что несмотря на низкий порог входа и наглядность, блюпринты — полноценный инструмент объектно-ориентированного программирования (ООП).
Оно требует практики, чтобы правильно всё организовывать, разделять по классам, компонентам и держать в чистоте. Кроме того, с помощью блюпринтов не получится отправить внешний запрос (например, по http), поработать с файловой системой компьютера или подключить стороннюю библиотеку. Для этого придется качать плагины или писать их самостоятельно. Но в остальном можно обойтись и дефолтными блюпринтами — внутри движка они умеют всё, что нужно.
В итоге игру можно написать только на блюпринтах (причём не только одиночную, но и сетевую) и во многих случаях разницы в производительности не будет. Хотя зависит от самой игры.
В Unity, кстати, тоже есть аналогичный инструмент. Он называется Playmaker, но стоит 45 долларов.
Study priceSession with mentor5 sessions pack 10 sessions pack Eligible for payments via wire transfer How it works? Москва, Russia GMT+03
Ведущий разработчикРаботаю с Unreal Engine около 8-ти лет, начиная с UDK. За это время работал в нескольких студиях и небольших командах, фрилансил, а также создал крупное сообщество по UE4.
В свободное время занимаюсь своими проектами и обучаюсь. 🤝 Can help withпройти обучение по программес выполнением рабочей задачи Новичкам помогу разобраться с интерфейсом Unreal Engine 4 Разобраться с программированием на Blueprints или C++ Помогу создать игру с нуля или настроить визуализацию Проконсультирую по процессам создания игр, от прототипирования до финализации Разобраться с Материалами, Анимациями, Ландшафтом, Освещением 💻 September 2020 — Основатель и Ведущий разработчик June 2014 — UEngine.ruОснователь и Администратор April 2018 — Pixonic September 2016 — NeuronHaze September 2015 — 🤟 Разработка и тестирование игровых локаций, импорт и настройка визуального контента (модели, анимации, материалы). Создание игровых локаций. Реализация геймплейных составляющих. Проектирование и разработка системы ИИ. Разработка второстепенных игровых механик. Верстка и настройка UI (UMG, HUD). Создание полноценного прототипа проекта для тестирования на живой аудитории. Работа включала в себя как создание клиента игры, так и разработка небольшого серверного решения для авторизации и подбора игр для пользователей. Проектирование и программирование архитектуры и игровых механик с нуля, интеграция сторонних библиотек (Android, iOS), оптимизация и профайлинг графической и программой составляющих проектов. Управление небольшой командой разработчиков, построение и планирование задач. Cut & Ship Небольшой собственный проект. Написание всего с нуля на UE4, интеграция сторонних SDK, интеграция UI от художника. Проект на двух месячный Джем. Сделано все с нуля, включая графика, звуки и техническая составляющая. Разработка и проектирования проекта с нуля на UE4. Работа со сторонними SDK (Android IOS). Ведение технической документации, работа с командой дизайнеров. 📰 К списку менторов Стоимость занятий Часовое занятие с ментором Пакет 5 занятий Пакет 10 занятий Пробные 15 минут Возможна оплата через юр. лицо Как проходят занятия? Москва, Россия GMT+03
Ведущий разработчикРаботаю с Unreal Engine около 8-ти лет, начиная с UDK. За это время работал в нескольких студиях и небольших командах, фрилансил, а также создал крупное сообщество по UE4.
В свободное время занимаюсь своими проектами и обучаюсь. 🤝 С чем могу помочьпройти обучение по программес выполнением рабочей задачи Новичкам помогу разобраться с интерфейсом Unreal Engine 4 Разобраться с программированием на Blueprints или C++ Помогу создать игру с нуля или настроить визуализацию Проконсультирую по процессам создания игр, от прототипирования до финализации Разобраться с Материалами, Анимациями, Ландшафтом, Освещением 💻 September 2020 — по настоящее время Основатель и Ведущий разработчик June 2014 — по настоящее время UEngine.ruОснователь и Администратор April 2018 — Pixonic September 2016 — NeuronHaze September 2015 — 🤟 Разработка и тестирование игровых локаций, импорт и настройка визуального контента (модели, анимации, материалы). Создание игровых локаций. Реализация геймплейных составляющих. Проектирование и разработка системы ИИ. Разработка второстепенных игровых механик. Верстка и настройка UI (UMG, HUD). Создание полноценного прототипа проекта для тестирования на живой аудитории. Работа включала в себя как создание клиента игры, так и разработка небольшого серверного решения для авторизации и подбора игр для пользователей. Проектирование и программирование архитектуры и игровых механик с нуля, интеграция сторонних библиотек (Android, iOS), оптимизация и профайлинг графической и программой составляющих проектов. Управление небольшой командой разработчиков, построение и планирование задач. Cut & Ship Небольшой собственный проект. Написание всего с нуля на UE4, интеграция сторонних SDK, интеграция UI от художника. Проект на двух месячный Джем. Сделано все с нуля, включая графика, звуки и техническая составляющая. Разработка и проектирования проекта с нуля на UE4. Работа со сторонними SDK (Android IOS). Ведение технической документации, работа с командой дизайнеров. 📰
BeginPlay и Tick события
Еще одна проблема, с которыми могут столкнуться разработчики на Блупринтах — в Object классе нет событий BeginPlay и Tick. Безусловно, вы можете их создать сами и вызывать из другого класса. Но согласитесь, что гораздо удобнее, когда это все работает из коробки.
Давайте для начала разберем, как сделать Begin Play. Мы можем создать доступную для перезаписи в БП функцию и вызывать ее в конструкторе класса, но тут есть ряд проблем, так как на момент конструктора ваш объект еще полностью не инициализирован.
Во всех классах существует функция PostInitProperties(), которая вызывается после инициализации большинства параметров и регистрации объекта в различных внутренних системах, например, для сборщика мусора. В ней как раз можно вызвать наше событие, которое будет использоваться в Блупринтах:
Будьте осторожны! По умолчанию PostInitProperties() вызывается и в редакторе.
Теперь мы можем зайти в наш БП объект и вызвать событие BeginPlay. Оно будет вызываться при создании объекта.
Перейдем к Event Tick. Тут простой функцией нам не обойтись. Tick объектов в движке вызывает специальный менеджер, к которому нужно как-то подцепиться. Однако, тут есть очень удобная хитрость — дополнительное наследование от FTickableGameObject. Это позволит автоматически сделать все, что нужно, и тогда достаточно будет просто подцепить необходимые функции:
Если вы отнаследуетесь от вашего объекта и создадите БП класс, то будет доступно событие EventTick, вызывающее логику каждый кадр.
Приветствую!
Хотел бы познакомить вас с относительно небольшим проектом, который я сделал c нуля примерно за 150 часов (50 заходов ~3 часа каждый) на Unreal Engine 4. Проект я делал в прямом эфире только на стримах раз в неделю (в общей сложности ушел год), попутно отвечая на вопросы пользователей.
Сам проект не предназначался как коммерческий. Целью я ставил на практике показать всю сложность разработки игр, а именно такие проблемы, как:
В конце всей серии стримов у нас получился играбельный прототип “Сурвайвл” шутера. Те, у кого стакан наполовину полон, смогут даже назвать это пре-альфой без сюжета.
Весь проект был реализован на визуальной системе программирования, под названием “Блупринты”. И конечно многие спецы могут назвать её ребяческой, разработать на ней можно спокойно даже относительно крупный проект. Более того, это можно сделать относительно быстро, как мы уже смогли доказать.
Сразу хочу ответить на вопрос: “Почему Блупринты, а не С++?”. Ну во первых, когда я начинал серию, плюсы я почти не знал. Хотя я и сейчас подобный сингл делал бы на БП. Во вторых, БП почти не уступают плюсам в нашем случае, но при этом дают ряд возможностей: Не позволяют наделать множество ошибок, возможных с плюсами, не приходится отвлекаться между БП и С++, понятнее новичкам. Да и они в нашем случае не намного медленнее, учитывая тот факт, что почти вся логика построена на событиях.
Мы так же успели немного поработать над графикой. К сожалению, ассеты делать времени у нас не было, поэтому мы часть оставили пустышками, часть сделали прямо в редакторе из примитивов, а некоторый контент позаимствовали из бесплатных демок Epic Games. Тем не менее, что-то успели сделать и сами, например систему дня и ночи, постобработку для воды и некоторые материалы объектов сцены.
В планы моих стримов так же стояли и проблемы, которые могут возникнуть при разработке. Их я специально решал в прямом эфире, дабы не только показать, с чем могут столкнуться юные разработчики, но и как отлаживать свой код, искать баги и писать свой код так, что бы все это дело можно было делать в два раза быстрее. Конечно опыта в программировании у меня не десятки лет, и это сказывалось на том, какие порой глупые ошибки я делал. Да и уверен, что многие разработчики могут оспорить множество моментов в процессе написания игры.
Естественно, полноценной игрой это вряд ли можно назвать, так как нету ни сюжета, ни цели в игре — только чистая механика. Тем не менее, я считаю, что результатом можно гордится и он вполне отражает то, для чего задумывался весь проект.
Список всего, что мы успели реализовать в нашей игре
Объектная система инвентаря
Впрочем, говорить о проекте можно бесконечно. И чтобы не превращать статью в книгу, предлагаю ознакомиться с игрой и возможностями по видео. А тем, кому стало действительно интересно, чуть ниже сможете найти записи всех стримов, ссылки на исходники и билд игры.
https://youtube.com/watch?v=1Ny2gwR_rSk%3Frel%3D0%26showinfo%3D1
Записи всех 50-ти частей стримов
Содержание по частям
Исходники на Git (загрузка ZIP архивом не работает, архив почему-то поврежден.)
Исходники на ЯДиск (Лицензия та же, что и в исходниках)
Билд игры
В будущем я и дальше планирую проводить подобные стримы. Например на очереди у нас стрим по мультиплеерному шутеру, а затем стратегия. Следить за стримами можно в нашей ВК группе.
Создание UObject
Прежде чем расширять наш класс возможностями, нам нужно его создать. Давайте воспользуемся редактором, чтобы генератор автоматически записал в хедер (.h) все, что нужно для работы.
Создать новый класс мы можем в Content Browser редактора, нажав кнопку New и выбрав там пункт New C++ Class.
Далее нам нужно выбрать сам класс. В общем списке его может не быть, поэтому раскрываем его и выбираем UObject.
Назовите ваш класс и выберите, в какой папке он будет храниться. Когда мы создали класс, можно зайти в студию, найти его там и начать встраивать все необходимые функции.
Новички, обратите внимание, что создается два файла: .h и .ccp. В .h вы будете объявлять переменные и функции, а в .cpp определять их логику. Найдите оба файла в вашем проекте. Если не меняли путь, то они должны быть в Project/Source/Project/.
Пока мы не продолжили, давайте в макросе UCLASS() над объявлением класса пропишем параметр Blueprintable. Должно получиться что-то вроде этого:
Благодаря этому можно создавать Блупринты, которые будут наследовать все, что мы сделаем с этим объектом.
Шаблоны и демо-проекты
Сразу после запуска движка вам предложат выбрать один из шаблонов. Можно, конечно, открыть пустой, но всегда легче переписывать и дополнять что-то готовое, если шаблон подходит к выбранному жанру.
Стоит обратить внимание на демки из лаунчера Epic Games (вкладка Learn/Изучить). Там можно найти очень много проектов на разные темы. Причём это практически полноценные прототипы игр, с логикой и графикой.
Демо идеально подойдут новичкам — их можно изучать или сделать свой проект на их основе. Все готовые шаблоны и демо можно использовать в коммерческих целях.
Лайфхак: можно собрать проект полностью на основе предложенного контента, а потом потихоньку заменять его на свой, оригинальный.
Репликация UObject
По умолчанию UObject’ы не реплицируются по сети. Как я описал выше, создается ряд ограничений, когда нужно синхронизировать данные или логику между сторонами, но при этом не хранить мусор в мире.
В Unreal Engine 4 репликация проходит как раз за счет мировых объектов. Значит просто создать объект в памяти и отреплицировать его никак не получится. Вам в любом случае понадобится владелец, который будет управлять передачей данных объекта между сервером и клиентами. Например, если ваш объект — это навык персонажа, то владельцем должен стать сам персонаж. Он же и будет проводником для передачи информации по сети.
Подготовим наш объект к репликации. Пока в хедере нам нужно задать лишь одну функцию:
IsSupportedForNetworking() определит, что объект поддерживает сеть и может быть отреплицирован.
Однако не все так просто. Как я написал выше, нужен владелец, управляющий передачей объекта. Для чистоты эксперимента создадим AActor, который будет его реплицировать. Сделать это можно точно так же, как и UObject, только родительский класс, естественно, AActor.
Новички, если вам требуется реплицировать объект в персонаже, контроллере или еще где-то, создайте соответствующий базовый класс через редактор, добавьте в него необходимую логику и уже от этого класса наследуйтесь в Блупринтах.
Внутри нам нужны 3 функции: конструктор, функция репликации подобъектов, функция, определяющая, что внутри этого AActor реплицируется (переменные, ссылки на объекты и прочее) и место, где мы создадим наш объект.
Не забудем создать и переменную, по которой будет храниться наш объект:
Внутри исходного файла мы должны все прописать:
Теперь ваш объект будет реплицироваться вместе с этим Actor’ом. Вы можете вывести его имя на тик, но уже на клиенте. Обратите внимание, что на Begin Play объект до клиента вряд ли успеет прийти, поэтому там смысла писать лог на нем нет.
Добавление компонентов из UObject’ов
В Блупринтах UObject нельзя спавнить компоненты для Actor’ов. Эта же проблема свойственна и Блупринтам ActorComponent. Не очень понятна логика Epic Games, так как в C++ это можно сделать. Более того, вы можете добавить компонент из Actor’а другому Actor объекту просто указав ссылку. Но сделать этого нельзя.
К сожалению, с данным пунктом я так и не смог разобраться. Если у кого найдется инструкция, как это сделать, буду рад выложить сюда.
Единственный вариант, который я могу предложить на данный момент — это сделать обертку в классе UObject, предоставляющую доступ к простому добавлению компонентов. Таким образом получится добавлять компоненты Actor’ам, но у вас не будет динамически создаваться входные параметры спауна. Зачастую, этим можно пренебречь.
Репликация переменных в UObject
В большинстве случаях реплицировать объект смысла нет, если в нем не содержится информация, которая так же будет синхронизироваться между сервером и клиентами. Поскольку наш объект уже реплицируется, то и передавать переменные не составит труда. Это делается так же, как и внутри нашего Actor’а:
Добавив переменную и пометив на репликацию, мы сможем ее реплицировать. Тут все просто и так же, как в AActor.
Однако есть небольшой подводный камень, который виден не сразу, но может ввести вас в заблуждение. Это будет особенно заметно, если вы создаете ваш UObject не для работы в C++, а подготавливаете его для наследования и работы в Блупринтах.
Суть в том, что переменные, созданные в наследнике в Блупринтах, реплицироваться не будут. Движок автоматически их не помечает и изменение параметра на сервере в БП ничего не меняет в значении на клиенте. Но и от этого есть лекарство. Для корректной репликации переменных БП вам нужно заранее их пометить. Добавьте пару строчек в GetLifetimeReplicatedProps():
Теперь переменные в дочерних Блупринт классах будут реплицироваться как положено.
Меши, материалы и эффекты
Предположим, у вас уже готов прототип игрового мира и механика геймплея. Теперь нужно импортировать модели и настроить материалы к ним, чтобы всё выглядело как нужно. Мы обойдёмся готовыми ассетами.
Движок поддерживает .fbx и .obj форматы 3D-моделей, а также все популярные форматы текстур. Импортировать их достаточно просто — можно даже закинуть всё в папку с проектом, и импорт произойдёт автоматически.
Ещё важно настроить материалы, то есть шейдеры. Обычно они пишутся кодом в других программах, но в Unreal Engine 4 и на этот случай есть визуальный инструментарий, который позволяет описать инструкции шейдера нодами. Может показаться запутанным, но на самом деле для простых материалов присоединить нужные текстуры и получить реалистичный вид не так сложно.
Добавив еще немного смешиваний, можно получить эффекты поинтереснее.
Не забудем и про визуальные эффекты. Сейчас в UE4 для них есть два редактора: модульный и нодовый. В первом собирается система частиц и эффектов с помощью модулей и настроек. А во втором можно создавать эффекты с помощью нодового редактора, очень похожего на редактор материалов. Там можно гибко настраивать эффекты для получения нужного результата.
Вот так преобразился прототип локации из начала статьи после импорта и настройки контента.
Настройка экземпляра через редактор
В UE4 есть еще одна удобная «фича» для работы с объектами — это возможность создать экземпляр во время инициализации и менять его параметры через редактор, тем самым настроив его свойства, не создавая дочерний класс только ради настроек. Особенно полезно гейм-дизайнерам.
Допустим, у вас есть менеджер модификаторов для персонажа и сами модификаторы представлены классами, в которых описываются накладываемые эффекты. Гейм-дизайнер создал пару модификаторов и указывает в менеджере, какие используются.
В обычной ситуации выглядело бы вот так:
Однако тут возникает проблема в том, что настроить модификаторы он не может и приходится создавать дополнительный класс для других значений. Согласитесь, не очень удобно иметь десятки классов в Content Browser, которые отличаются лишь значениями. Исправить это несложно. Можно добавить внутрь USTRUCT() пару полей, а также указать в объекте-контейнере, что наши объекты будут экземплярами, а не просто ссылками на несуществующий объект или классами:
Одного этого мало, теперь необходимо указать, что та самая переменная с классом будет экземпляром. Это уже делается там, где вы храните объект, например, в менеджере модификаторов персонажа:
Обратите внимание, что мы используем именно ссылку на объект, а не на класс, так как экземпляр будет создан сразу при инициализации. Теперь мы можем зайти в окно редактора выбрать класс и настроить значения внутри экземпляра. Это гораздо удобнее и более гибко.
Немного о UObject
UObject — базовый класс почти для всего, что есть в Unreal Engine 4. От него наследуется подавляющее большинство объектов, которые создаются у вас в мире или просто в памяти: объекты на сцене (AActor), компоненты (UActorComponent), разные типы для работы с данными и прочие.
Сам класс хоть и легче производных, но при этом достаточно функционален. Например, он содержит многие полезные события, такие как изменение значений переменных в редакторе и базовые функции для сети, которые не активны по умолчанию.
Объекты, созданные этим классом, не могут находиться на сцене и существуют исключительно в памяти. Их нельзя добавить как компоненты к Actor’ам, хотя он может являться своего рода компонентом, если самому реализовать необходимый функционал.
Для чего мне UObject, если AActor уже поддерживает все, что нужно? В общем-то, примеров использования масса. Самый простой — предметы для инвентаря. На сцене, где-то в небе, хранить их нецелесообразно, поэтому можно хранить в памяти, не нагружая рендер и не создавая лишних свойств. Для тех, кто любит технические сравнения, то AActor занимает килобайт (1016 байт), а пустой UObject всего 56 байт.
RPC события в UObject
RPC (Remote Procedure Call) события — это специальные функции, вызывающиеся на другой стороне сетевого взаимодействия проекта. С помощью них вы можете вызвать функцию с сервера на других клиентах и с клиента на сервере. Очень полезно и часто используется при написании сетевых проектов.
Если вы не знакомы с ними, рекомендую почитать один материал. В нем описывается использование в C++ и в Блупринтах.
В то время как в Actor или в компонентах с их вызовом проблем нет, в UObject события срабатывают на той же стороне, где и были вызваны, что приводит к невозможности выполнить удаленный вызов, когда это нужно.
Взглянув на код компонентов (UActorComponent), мы можем найти несколько функций, которые позволяют передавать вызовы по сети. Так как UActorComponent наследуется от UObject, мы можем просто скопировать необходимые участки кода и вставить в наш объект, чтобы он работал как нужно:
С этими функциями мы сможем вызывать RPC события не только в коде, но и в Блупринтах.
Обратите внимание, что для вызова Client или Server событий необходим владелец, у которого Owner — наш игрок. Например объектом владеет персонаж пользователя или же предмет, у которого Owner — это Player Controller игрока.
Глобальные функции в Блупринтах
Если вы когда-либо создавали Object Блупринт, то могли заметить, что в них нельзя вызвать глобальные функции (статичные, но для понятности назовем так), которые доступны в остальных классах, например, GetGamemode(). Создается ощущение, что вы просто-напросто не можете делать в Object классах, из-за чего вам приходится либо передавать все ссылки при создании, либо же как-то извращаться, а иногда выбор и вовсе падает на класс Actor, который создается на сцене и поддерживает все на свете.
А вот в С++, конечно же, таких проблем нет. Однако гейм-дизайнеру, который играется с настройками и добавляет разные мелочи, не скажешь, что нужно открыть Visual Studio, найти соответствующий класс и в функции doSomething() получить игровой режим, изменив в нем очки. Поэтому крайне важно, чтобы дизайнер мог зайти в Блупринт и двумя щелчками мыши сделать то, в чем заключается его работа. Сэкономите и его время, и ваше. Впрочем, Блупринты для этого и придуманы.
Суть в том, что когда вы ищите или вызываете функции в контекстном меню в Блупринте, те самые глобальные функции, которым требуется ссылка на мир, пробуют вызвать функцию внутри вашего объекта, ссылающуюся на него. И если редактор видит, что функции нет, то понимает, что использовать ее он не сможет и не показывает в списке.
Впрочем, и от этого есть лекарство. Даже два.
Давайте вначале рассмотрим вариант для более удобного использования в редакторе. Нам нужно будет переопределить функцию, которая возвращает ссылку на мир и тогда редактор поймет, что в самой игре она сможет работать:
Теперь она определена и редактор будет понимать, что в целом объект способен получить нужный указатель (хоть он не валидный) и использовать глобальные функции в БП.
Обратите внимание, что владелец (GetOuter()) тоже должен иметь выход к миру. Это может быть другой UObject с определенным GetWorld(), компонент или Actor объект на сцене.
Есть и иной способ. Достаточно добавить в макрос UCLASS() при объявлении класса метку о том, что статичным функциям в БП будет добавляться параметр WorldContextObject, в который подается любой объект, служащий проводником в «мир» и глобальным функциям движка. Этот вариант подойдет тем, у кого в проекте может быть несколько миров одновременно (например, игровой мир и мир для спектатора):
Если ввести в поиск в БП GetGamemode, он появится в списке, как и другие подобные функции, и в параметре будет WorldContextObject, в который нужно передавать ссылку на Actor.
К слову, можно просто подавать туда владельца нашего объекта. Я рекомендую создать функцию на Actor’а, это будет всегда полезно для объекта:
Теперь можно просто использовать глобальные функции в сочетании с нашей Pure функцией для получения владельца.
Если вы во втором варианте так же объявите GetWorld() как и в первом варианте, то сможете подавать в параметр WorldContextObject ссылку на себя (Self или This).
Info
Есть в Unreal Engine еще один интересный класс. Это AInfo. Класс, унаследованный от AActor, не имеющий визуального представления в мире. Info используют такие классы, как: игровой режим, GameState, PlayerState и прочие. То есть классы, которые поддерживают разные фишки от AActor, например, репликацию, но при этом не размещены на сцену.
Если вам нужно создать дополнительный, глобальный менеджер, который должен поддерживать сеть и все вытекающие Actor класса, то можно использовать его. Вам не придется манипулировать классом UObject, как описано выше, чтобы заставить его, например, реплицировать данные.
Однако учтите, что хоть и у объекта нет координат, визуальных компонентов и он не рендерится на экране, он все равно является наследником Actor класса, а значит, настолько же тяжелый, как и родитель. Резонно использование в малых количествах и ради удобства.
Заключение
UObject нужен очень часто, и я советую пользоваться им всегда, когда Actor в действительности не нужен. Жаль, что он немного ограничен, но это одновременно и плюс. Иногда приходится повозиться, когда вам нужно использовать нестандартный шаблон, но главное, что все основные ограничения можно снять.
Если вы будете часто работать с объектами из Блупринтов, но не хочется постоянно создавать классы и добавлять в них эти возможности, можно просто создать один класс UObject, с поддержкой всего, что вам может понадобиться в проекте, а дальше создавать дочерние от него Блупринты и работать в них.
Надеюсь, статья будет полезна тем, кто изучает или работает с Unreal Engine 4. Если вдруг какая-то часть не компилируется, то можете сообщить об этом в комментариях или в личку. Также буду очень благодарен, если кто-то знает еще различные полезности, связанные с UObject.
Второй цикл статей для начинающих разработчиков игр подошёл к концу — вспомним, с чем мы успели познакомиться.
Цель этих статей — показать, что начать разрабатывать игры может любой. Для этого не нужно заканчивать профильные университеты или досконально знать программирование.
В прошлом разделе «Геймдизайн» мы создавали концепт, проверяли идеи и формулировали уникальные черты будущей игры. Теперь пришло время показать игровой прототип игры или основной механики. Среди участников мы снова разыграем лимитированное издание PlayStation 4 Pro — Spider-Man Limited Edition.