Тут очень интересно. Как я писал ранее, BP - очень мощный инструмент. Вообще, BP использует функции, написанные на C++, которые, кстати, довольно легко найти, если покопаться в движке (об этом будет в этом посте). На самом то деле, мы пишем не на чистом C++, а используем его синтаксис, разные особенности, используя SDK движка. Ну где вы видели, например, класс Character или структуру FRotator в чистом C++? Собственно, в BP реализовали циклы, математические операции, функции, переменные и разное прочее, привязав SDK движка, чтобы можно было обходиться без Visual Studio. Даже если вам не хватает того функционала, что идет телегой с движком, вы всегда можете написать свой плагин для движка (над чем я и потел, что так долго не выпускал пост) на C++, в который можно вкрутить свои библиотеки и код на чистом C++ и настроить все так, чтобы движок видел все функции и предоставлял их использование в редакторе BP. Тут уже дело удобства. Просто, как я, опять же, писал ранее, BP может разрастись в не хилую паутину, в которой будет уже довольно трудно разобраться. BP можно раскидать по функциям, которые тоже создаются в BP. Но есть некоторые задачи, которые не очень удобно решаются (или вообще не решаются) использованием BP. Серьезно, это очень мощный инструмент и при работе с этим движком вы никуда не денетесь от использования BP.
И самый частый вопрос: "Как с тобой связаться?".
Долго я не отвечал на эти вопросы, ибо не понимаю чем не устраивает вас пикабу? Ведь тут можно задать вопрос, на который я отвечу либо постом либо комментарием и все смогут увидеть решение той проблемы, с которой вы столкнулись. Работу я имею, уходить никуда не собираюсь в ближайшее время. Ну нравится мне коллектив и проекты, над которыми я работаю. Да и куда то уехать из города я пока не имею возможности т.к. через пару месяцев у меня защита, а потом магистратура и т.д. и т.п. По текущему проекту и реализации того, над чем я сейчас работаю, я отвечать не буду, т.к. это глупо сливать информацию третьим лицам. Я выкладываю проекту на своем гуглодиске, переходя по которой вы видите почту владельца этого диска. Вот на эту почту (mealtris@gmail.com ага, сложно было догадаться:) ) и можете задавать вопросы, она рабочая.
Ну и раз начали мы с BP, так и продолжим с BP.
Дополним ответ на вопрос выше. Я тут почитал особенности UE 4.11, который сейчас готовят к выпуску и там может появиться конвертер BP в C++ код! Но конвертация происходит на этапе финальной сборки проекта. Все-равно, круто же?
Это еще один пруф к тому, что обойтись без C++, если достаточно функционала движка и не требуется написание своих плагинов, и использования своих библиотек, вполне можно, но если вы хотите получать данные из какого то стороннего софта или подцепить к движку какое то устройство, с которым он не умеет работать, и нет плагина для него, тогда увы. Про плагины поговорим позже.
Стоит дополнить мой предыдущий пост, в котором я благополучно забыл скачать, что если вы будете работать совместно с движком, пользуясь гитом, но не будете использовать C++, тогда при возникновении конфликтов слияния (оба человека изменили один и тот же файл), вы не сможете его разрешить объединением локального и удаленного варианта, а сможете или заменить конфликтующий файл своим, или удалить свой, взяв удаленный.
В общем, про BP и С++ можно спорить еще очень много и долго, но тут мы будем использовать и то, и другое :)
Вообще, BPидеальны для того, чтобы протестировать работу какого-то вашего алгоритма перед написанием его на C++ из-за скорости их компилляции, чем C++ похвастаться не может, отчасти из-за того, что еще идет пересборка редактора, когда вы добавляете новые функции в своих классах. Вот ситуация - вы проверили алгоритм, вам он подходит, но, когда вы начали переносить его в C++, вы не можете найти там те функции, которые вы использовали в BP. Об этом сейчас и поговорим.
Как искать функции BP, которые вы не нашли в C++.
Это происходит, т.к. не подключена та или иная библиотека. Возьмем простенький пример. Вам потребовалось найти длину вектора, но вы, вводя название той функции, не находите ее. Просто вы пытаетесь ее найти в родительском или своем текущем классе, а она находится в сторонней библиотеке, подключенной к движку, но не к вашему классу!
Если навести на блок BP, в появившемся описании последней строчкой будет название библиотеки.
Если это библиотека, которая была в движке по стандарту, вы можете найти полное ее описание в документации к движку. Нас интересует что подключить, чтобы ей воспользоваться. Переходим в поиск по API и вводим название библиотеки, выбираем поиск по API и переходим по нужной вам ссылке. В случае с этой библиотекой, мы увидим следующее:
Выбираем UKismetMathLibrary и нас перенаправит на следующую страницу, где описана иерархия наследования, а в графе References, мы видим нужный нам для работы путь к хэдеру.
Подключаем его к нашему классу, после чего мы сможем пользоваться той функцией, которую искали, обращаясь к библиотеке.
Как я удачно выбрал функцию для примера) Если мы попробуем ввести VectorLength, то такой функции в только что подключенной библиотеке мы не найдем. Просто она называется по другому, но она там есть. Просто при создании BP функций можно задавать другое название, которое будет отображаться в редакторе BP. В этих случаях нам нужно нажать правой кнопкой по названию нашей библиотеки и перейти к определению.
У вас откроется хэдер файл данной библиотеки, в котором нужно выполнить поиск нашей функции. Просто введите в поиск часть описания функции, которое появляется в BP при наведении мыши на блок и все, вы находите нужною вам функцию.
После чего спокойно используете ее.
Пора все же перейти к следующей части поста.
Состав проекта.
Если вы зайдете в папку с проектом, вы увидите следующее:
Давайте рассмотрим его составные части.
В папке Content у нас хранится весь контент проекта. Там и графика, и анимации, и уровни, там же хранятся и BP классы. В общем, это самая увесистая папка проекта, которая, кстати, полностью состоит из .uasset файлов, представляющих собой бинарники, которые воспринимаются нашим движком уже как модели, анимации, звуки и т.д.
Вообще, .uasset содержит оригинал вашего файла и пути ко всем связанным с этим ассетом ассеты. Т.е при при перемещении ассета того же оружия, путь к которому хранится в ассете персонажа, не используя движок, а перемещая это жестко из папки, то ассет персонажа потеряет оружие, а движок выведет кучу ошибок по поводу того, что по такому то пути нет ассета с таким то именем. Т.е. перемещение нужно делать используя движок в контент браузере.
В папке Config хранятся настройки проекта и движка для этого проекта.
В папке Source хранятся исходники классов, написанных нами от нашего проекта.
Pikabu.uproject - это уже файл проекта, который хранит какие сторонние плагины и модули подключены для использования в проекте, требуемую версию движка, версию и т.д.
Это минимум, требуемый для запуска проекта на вашем компьютере. В остальных папках у нас находится кэш, бинарники, сгенерированный проект VisualStudio, бэкапы и прочее, что при изменениях пересобирается заново. Т.е. их можно просто удалить и ничего ужасного не произойдет. Движок все сгенерирует заново.
Ну стоит добавить, что собранный .exe файл проекта будет находиться по пути .../Saved/StagedBuilds.
В случае с гитом, целесообразно отслеживать только файл проекта и папки source и config, т.к. изменения в остальных файлах не будут индексироваться. А тот же контент можно хранить на вашем сервере или любом облаке с автосинхронизацией и т.д.
Ну а теперь сделаем то, что нам понадобится для следующего урока. В следующем уроке мы будем ковырять персонажа, а для этого нам нужна адекватная моделька, а не порящие в воздухе руки. По-этому поговорим о миграции ассетов из одного проекта в другой.
Миграция.
Для начала найдем нам модельку, которая будет в бесплатном доступе и за которую мне не настучат по голове :D Благо, как отмечали в комментариях, есть у эпиков человек, который рассказывает о движке и заливает примеры работы с движком.
Зайдите в EpicLauncher (который, кстати, на русский перевели) и перейдите во вкладку "Узнать/Learn", а там найдите проект "ContentExamples".
Кстати, в этом же разделе можно взять себе разные крутые и красивые демо-проекты движка, которые показывают уровень графики и вообще того, что можно сделать в движке.
P.S. некоторые из них требовательны к сильным железкам. Они все рендерятся в реальном времени. В общем, это мультики, демонстрирующие функционал движка.
Скачав этот проект, запускаем его и передаем привет компилятору шейдеров)
В этом проекте есть куча интересностей, к которым мы еще будем возвращаться, но позже. Считайте это отчасти сборником спойлеров.
В общем, сейчас нас интересует только модель человека, его материалы и пак анимаций к нему. Все из этого мы мигрируем в наш проект.
Что вообще такое миграция? Как я писал выше, в .uasset важно сохранять структуру проекта, чтобы связанные ассеты не потеряли друг друга. Например в одном анимационном ассете имеется путь к скелету, да и вообще, при импорте анимации в проект, вы должны указывать где у вас находится скелет от той модели, для которой она предназначена. В монтажной анимации вообще может быть несколько анимаций со звуками и системами частиц, в которых еще пути на материалы, текстуры и т.д.
Открыв этот проект, вы же не знаете что с чем связано, а вот движок это все знает и может даже отобразить карту связей, если нажать правой кнопкой мыши по ассету и нажать на ReferenceViewer, после чего откроется вот такая вот штука.
В общем, что делает миграция? Миграция просматривает все эти связи и выявляет все ассеты, которые любым образом связаны с тем, который вы хотите мигрировать себе в проект, а затем копирует их к вам. Мигрировать можно в любую папку, но для использования, ее содержимое обязательно нужно перенести в корень вашей папки content.
Стоит отметить, что персонажа из какого-то проекта, который был написан на C++, вы мигрировать так, чтобы оно сразу же заработало в другом проекте, не сможете, т.к. миграция может работать только с BP объектами, а если BP наследован от C++ класса, которого изначально нет в движке и в вашем проекте, тогда он и работать не будет.
Нам нужна моделька персонажа, находим ее по пути из скриншота, жмем правой кнопкой, asset actions -> Migrate
С этой моделькой в наш проект переедут еще и все материалы от нее, скелет и физический ассет. Но анимации по умолчанию с моделькой не связаны. Их мигрируем так же, но уже кликом по папке Animations -> Migrate.
Кстати, в той папке, где была модель персонажа, еще есть моделька автомата, можете ее тоже прихватить с собой. Пригодится.
Эти анимации захватят с собой скелет, который у нас уже есть, можете согласиться с заменой.
Еще в этой папке с анимациями есть анимации от другой модели. Папку Retargeting можно будет удалить, как и скелет от другой модели.
Почему именно эта модель? У нее есть все анимации для построения адекватного locomotion (движение вперед, назад, влево, вправо) и позы смещения прицелов для построения BP для этого. Мы же хотим адекватно двигаться и целиться?) Жаль, что я такой себе моделлер, но ничего.
Оставляем пока эту модельку до следующего урока. Еще вы можете захватить папке Blendspaces, о которых я расскажу в следующем уроке, но вы можете с ними поиграться уже сейчас)
Двигаемся дальше. Нужно бы рассказать про настройки движка, чтобы не объяснять это в следующем уроке.
Перейдя в настройки, мы увидим вот такое вот окошко, в котором сейчас нас интересует вкладка Maps & Modes.
Здесь настраиваются параметры проекта вроде стандартных карт и выбора классов персонажа игрока и прочего.
Game default map - первая карта, которая будет открываться при запуске игры.
Editor Startup map - карта, которая первой открывается в движке
Transition map - переходная карта, которая откроется во время закрывания старой и запуска новой карты. Вроде окна с надписью "загрузка".
Default game mode - здесь задается игровой режим, который будет выбираться по стандарту, если на конкретном уровне не задан никакой другой.
В Game Mode выбирается Default pawn class - класс персонажа, которым будет управлять игрок.
HUD Class - то, что будет видеть игрок. Сюда лепятся всякие прицелы если делать их текстурой, текстуры каких то эффектов при низком хп и т.д.
Player controller class - класс контроллера игрока. Т.е. то, как будет он управляться. У нас, скорее всего, будет стандартный.
Кстати, ничего из этого не меняется, т.к. выбрал режим, который у нас в исходниках и нааписан на C++, где кодом прописаны эти параметры. В следующем уроке это все переделаем.
На разных уровнях можно менять игровой режим на другой в настройках уровня. Т.е. мы можем на разных уровнях давать игроку побегать другим персонажем с другими особенностями. В разные game mode можно добавлять разных менеджеров, которые будут храниться в одном экземпляре, и которых потом смогут получать любые актеры на уровне. Например можно сделать счетчик убийств, которому будут сообщать ИИ о своей смерти, а уже сам этот счетчик будет собирать информацию о количестве убийств игрока.
Game mode живет от начала и до конца жизни уровня.
Чтобы посмотреть, как работает Game mode, можете удалить с карты персонажа, которым мы сейчас бегаем и запустить игру. Вы все-равно будете играть этим персонажем, т.к. он указан в game mode. Вместо персонажа на уровне появится точка Network player start, перемещая которую, вы выбираете место, в котором будет появляться игрок.
Теперь поговорим о назначении управляющих кнопок.
В тех же настройках в разделе Engine, есть вкладка input.
Здесь вы можете создавать базовые события нажатия на какие то клавиши. В первом уроке мы ставили на кнопку 0 запуск вращения квадрата. Делали мы это в BP уровня, т.е. эта кнопка бы работала только на этом уровне. Здесь, можно так сказать, выставляется управление игрой. Что делать при вращении мыши, нажатии клавиш и т.д.
Вы задаете название, выбираете что будет генерировать это событие и далее уже прописываете что будет выполняться при нажатии на заданную кнопку в ваших классах. т.е. на конкретную кнопку разным персонажам можно задать разные функции.
Вы задаете название, и далее можете обрабатывать реакцию на событие с этим названием. Возьмем выстрел, например. Вот так он задается в коде.
На событие с именем "Fire", возникающем при нажатии кнопки, вызовется функция OnFire, где у нас пока сейчас прописан одиночный выстрел. Это же проворачивается и в BP.
Ну что же, еще немного добавил стартовой информации и уже нужно переходить к следующему посту. У меня закончилась возможность прикреплять картинки к посту, значит пора заканчивать, и, видимо, часть следующего урока будет в видео, т.к. из-за ограничения не влезет все в один пост...
Ну и по традиции ГУГЛОДИСКОССЫЛКА для тех кому лень мигрировать модельку. Ориентировочно на среду будет пост про персонажа.