unreal engine 4 blueprints обучение
(Перевод) Введение в разработку C++ в UE4
Часть 1. Введение. Создание класса и добавление свойств. Расширение класса С++ с помощью Blueprint.
Часть 2. Классы геймплея. Структуры. Отражение (reflection) в Unreal. Object/Actor итераторы. Менеджер памяти и сборщик мусора.
Часть 3. Префиксы в именах классов. Целочисленные типы. Типы контейнеров. Итераторы контейнеров. Цикл For-each, хеш-функции.
Часть 4. Бонусная. Unreal Engine 4 для Unity разработчиков.
Эта статья является переводом части документации по UE4. Оригинальную статью вы можете найти пройдя по это ссылке.
Unreal C++ очень крут!
Это руководство покажет вам как писать код на С++ в Unreal Engine. Не переживайте, разработка на С++ в Unreal Engine весёлая, и совершенно не сложная, чтобы её начать. Нам нравится думать о Unreal C++ как о «помогающем C++» *, поскольку мы создали множество разных фич чтобы сделать C++ легче для всех!
* буду рад, если кто предложит лучший перевод «assisted C++», но пожалуйста в личку.
Перед тем как мы начнем, важно чтобы вы были уже знакомы с C ++ или другим, схожим языком программирования. Это руководство написано для разработчиков имеющих опыт с C++. Если вы знаете, C#, Java или JS, вы найдете множество знакомых аспектов.
Если у вас совершенно нет опыта разработки, вы можете изучить гид по визуальному скриптингу при помощи Blueprint*. После изучения этого руководства, вы сможете создавать игры с помощью Blueprint**.
Вы можете писать «старый добрый С++ код», но вы будете более продвинутым разработчиком, после прочтения этого руководства и изучении модели разработки в Unreal.
C++ и Blueprints
UE предоставляет два метода для создания элементов геймплея — C++ и Blueprint. С++ программисты добавляют основные блоки геймплея, таким образом, чтобы дизайнеры (тут имеется ввиду левел-дизайнер, а не художник) с помощью этих блоков мог создавать свои элементы геймплея для отдельного уровня или всей игры. В таком случае, программисты работают в своем (своей) любимой IDE (например — MS Visual Studio, Xcode), а дизайнер работает в Blueprint редакторе UE.
API геймплея и фреймворк классов полностью доступны из обоих систем. Обе системы можно использовать по отдельности, но используя их вместе вы получаете более мощную и гибкую систему. Это значит, что лучшей практикой будет слаженная работа программистов, которые создают основы геймплея и левел-дизайнеров, которые используют эти блоки для создания увлекательного геймплея.
С учетом всего вышесказанного, далее будет рассмотрен типичный рабочий процесс программиста C++, который создает блоки для дизайнера. В этом случает вы должны создать класс, который в дальнейшем будет расширен с помощью Blueprint, созданного дизайнером или другим программистом. В этом классе мы создадим различные свойства (переменные), которые сможет задать дизайнер. На основе этих заданных значений, мы собираемся извлечь новые значения созданных свойств. Данный процесс очень прост благодаря инструментам и макросам, которые мы предоставляем для вас.
Мастер классов
Самое первое что требуется сделать это воспользоваться мастером классов (class wizard) предоставляемый UE, для создания базы будущего С++ класса, который в дальнейшем будет расширен с помощью Blueprint. Ниже показано, каким образом происходит выбор при создании нового класса, дочернего от класса Actor.
Далее требуется ввести название вашего класса. Мы воспользуемся именем по умолчанию (MyActor).
После того как вы создадите класс, мастер генерирует файлы и откроет IDE, таким образом что вы сразу можете начать редактировать его. Ниже приведен полученный таким образом код созданного класса. Для получения доп. информации о мастере классов, вы можете перейти по этой ссылке.
Мастер классов генерирует класс с методами BeginPlay() и Tick(), со спецификатором перегрузки (override). Событие BeginPlay() происходит когда Actor входит в игру, в состоянии разрешённом для игры (playable state). Хорошей практикой является инициирование геймплей-кода вашего класса в этом методе. Метод Tick() вызывается каждый кадр с параметром, который равен времени, прошедшему с последнего своего вызова. В этом методе должна содержаться постоянно повторяющаяся логика. Если у вас она отсутствует, то лучше всего будет убрать данный метод, что немного увеличит производительность. Если вы удалили код данного метода, убедитесь что вы так же удалили строку в конструкторе класса, которая указывает, что Tick() должен вызываться каждый кадр. Ниже приведет код конструктора с указанной строкой:
Создание свойств, отображающихся в редакторе
Теперь у нас есть собственный класс. Давайте создадим несколько свойств, которые могут быть использованы другими разработчиками, непосредственно в UE. Для отображения свойства в редакторе требуется использовать специальный макрос UPROPERTY(). Все что требуется сделать, это написать макрос UPROPERTY(EditAnywhere) перед объявлением переменной, как написано ниже:
Это все что требуется сделать, чтобы редактировать данное значение в редакторе. Есть еще несколько путей, для указания каким образом и где данная переменная редактируется. Это делается с помощью указания доп. опций в макросе. К примеру, если вы хотите чтобы данное свойство было сгруппировано в разделе с другими соответствующими свойствами, вы должны указать категорию, как это указанно ниже:
Теперь, пользователи будут видеть вашу переменную помещенную в категорию с заголовком «Damage». В этой категории так же могут быть другие свойства, у которых указана такая же категория. Это отличный способ размещать наиболее часто используемые переменные вместе.
Теперь сделаем свойство доступным из Bluerpint:
Как вы можете увидеть, мы указали специальный параметр, для возможности чтения и записи свойства. Вы так же можете использовать другую опцию — BlueprintReadOnly, чтобы ваши переменные в редакторе указывались как константные. Кроме этого доступны многие другие свойства, передаваемые макросу UPROPERTY, ознакомиться с которыми можно перейдя по ссылке.
Перед тем как перейдем к следующему разделу, давайте добавим несколько переменных нашему классу. У нас уже имеется переменная хранящая полный урон, который может нанести Actor, но давайте считать, что урон может производиться длительное время. Код ниже содержит одну новую переменную доступную для редактирования левел-дизайнером и одну недоступную для редактирования:
Как видно, DamageTimeInSeconds свойство, которое доступно для редактирования в редакторе. DamagePerSecond будет вычисляться, как вы увидите позднее, на основе значения заданного в DamageTimeInSeconds, например, левел-дизайнером. Флаг VisibleAnywhere указывает что свойство отображается, но не может быть изменено. Флаг Transient означает что это свойство нельзя сохранить или прочитать с диска, то есть полученное значение является непостоянным. На картинке ниже показано как отображаются эти свойства в разделе значений по умолчанию нашего класса.
Установки значений по умолчанию в конструкторе
Установка начальных значений переменных происходит как и в обыкновенном C++ классе — в конструкторе. Ниже приведены два примера, каким образом это можно сделать, оба примера эквиваленты по функциональности:
Вот тот же кусок окна, но уже с заданными значениями в конструкторе
Так же возможно задавать начальные значения основанные на значениях заданных в редакторе. Эти данные задаются после конструктора, для этого требуется использовать метод PostInitProperties(). В данном примере TotalDamage и DamageTimeInSeconds задаются левел-дизайнером. Независимо от того, заданны ли эти значения из редактора, вы по прежнему можете задать требуемые начальные значения, как мы сделали это ранее.
Заметка: если вы не задаете значения по умолчанию, они автоматически будут установлены в 0 или nullptr для значений указателей.
Тот же кусок окна, что и ранее, но уже после добавления PostInitProperties() в цепь вызовов.
Горячая перезагрузка.
UE 4 предоставляет возможность, которая возможно удивит вас, если вы привыкли к обычному программированию на C++ в других проектах. Вы можете скомпилировать добавленный вами С++ код без перезапуска редактора. Есть два пути сделать это:
1. Если редактор запущен, сделайте билд в Visual Studio или Xcode, как вы обычно это делаете. Редактор обнаружит новые скомпилированные DLL и перезагрузит ваши изменения сразу же.
Заметка: Если у вас приатачен дебаггер, вы должны открепить его, в начале, иначе VS не позволит вам сделать build.
2. Или просто нажмите на Compele в основном тулбаре в редакторе.
Вы можете использовать эту возможность по мере продвижения по данному руководству.
Расширение С++ класс с помощью Blueprint
До этого мы создали простой геймплей-класс, при помощи С++ мастера классов и добавили в него несколько переменных. Теперь мы изучим на то, как пользователь может создавать уникальные классы из наших скромных набросков.
Первое, что требуется сделать, это создать Blueprint класс из нашего AMyActor класса. Обратите внимание, что на изображении ниже имя базового класса указанно как MyActor, а не AMyActor. Это сделано для того, чтобы спрятать соглашения об именах, которое используется в наших инструментах от пользователя, делая имена более удобными для него.
После нажатия на Select, будет создан новый Blueprint с дефолтным именем. Мы зададим ему имя CustomActor1, как указанно на изображении из Content Browser’а ниже.
Это наш первый класс, который наш пользователь будет редактировать. Во-первых, поменяем значения наших переменных. В данном случае выставим TotalDamage равным 300 и время, в течении которого наносятся эти повреждения равным двум секундам. Вы можете увидеть это на картинки ниже:
Погодите… Наша расчетная величина не соответствует нашему ожиданию. Оно должно быть 150, но мы видим значение равное 200. Это происходит потому, что в данным момент мы вычисляем значения сразу после инициализации значений, которое происходит в момент загрузки. Но у нас происходят изменения времени выполнения в редакторе (runtime changes), которые не учитываются. Эту проблему легко решить, поскольку движок уведомляет целевой объект о событии, которое вызывается при изменении в редакторе. Код ниже показывает, что именно требуется добавить для расчета новых значений, полученных при изменении переменных в редакторе:
Заметьте, что метод PostEditChangeProperty расположен внутри директивы, которая указывает, работаем мы в редакторе или нет. Это сделано для того чтобы при билде, игра содержала только необходимый для неё код, без лишних строк, которые увеличивают размер исполняемого файла, без необходимости. Теперь, после перекомпиляции, значение DamagePerSecond будет соответствующим нашему ожиданию. Это указанно на картинки ниже.
Вызов C++ методов в Blueprint
До сих пор мы изучали работу с переменными. Кроме этого требуется изучить еще одну важную базовую вещь, перед тем как более детально изучать движок. В процессе создания геймплея, пользователь должен иметь возможность вызывать в Blueprint функции созданные C++ программистом. Для начала давайте сделаем чтобы метод CalculateValues() можно было вызывать из Bluerpint.
Макрос UFUNCTION() содержит описание, каким образом наша С++ функция обрабатывается системой рефлексии. Опция BlueprintCallable указывает возможность обработки данного метода в виртуальной машине Blueprint’ов (далее Blueprint VM). Для того, чтобы контекстное меню (вызываемое правой кнопкой мыши) работало должным образом, каждый метод, вызов которого разрешен редактором, должен содержать имя категории. Изображение ниже показывает как именно категории отображаются в контекстном меню:
Как видите, метод может быть выбран в категории Damage. Blueprint-код ниже показывает, каким образом происходят изменения в значении TotalDamage, с последующим вызовом метода для пересчета зависимых значений.
Тут мы используем метод, описанный ранее, для пересчета зависимых свойств. Большая часть методов движка доступны для вызова из Blueprint, при помощи макроса UFUNCTION(), так чтобы разработчики могли создавать игры без написания С++ кода. Тем не менее, более грамотным подходом будет использования С++ для создания основных блоков геймплея и кода, чья производительность критична, а применение Blueprint для кастомизирования созданного поведения или конструирование нового, в основе которого лежит созданный код.
Теперь, когда наши пользователи могут вызывать ваш C++ код, рассмотрим еще один способ вызова C++ кода в Blueprint. Этот подход позволяет вызывать в С++-коде функции реализованные в Blueprint. Таким образом можно уведомить пользователя о событиях, на которые они могут реагировать тем образом, которым считают нужным. Часто это бывает создание эффектов или другие графические взаимодействия, как показ/сокрытие объектов. Фрагмент кода ниже содержит метод, который реализован в Blueprint:
Эта функция вызывается как и обычная С++-функция. UE генерирует основу реализации С++ функции для правильного вызова ее в Blueprint VM. Обычно мы называем это Thunk(Преобразователь). Если Blueprint не реализует тело функции, то её поведение представляет С++-функцию с пустым телом, которое ничего не делает. Что делать, если мы хотим обеспечить С++ реализацию по умолчанию и сделать возможным переопределения ее в Bluerpint. Макрос UFUNCTION() имеет опцию для этого случая. Фрагмент кода ниже показывает, какие изменения в заголовочном файле нужно сделать, чтобы добиться этого:
Эта версия метода по-прежнему преобразует метод для его вызова в Blueprint VM. Каким образом мы должны обеспечить реализацию по умолчанию? Инструменты так же генерируют новое определение метода с постфиксом _Implementation(). Мы должны представить вашу версию этого метода или ваш проект не будет слинкован. Вот реализация для указанного выше определения:
Теперь этот метод вызывается когда Blueprint не переопределяет его. На заметку: в будущих версиях билд инструментов автосгенерированное определение _Implementation() будет убрано и его нужно будет явно добавлять в заголовок. В версии 4.7 автогенерация этого определения по-прежнему происходит.
Теперь вы изучили основы разработки геймплея и методы совместной работы с пользователями для создания более разнообразного геймплея. Пришло время вам выбрать ваши собственные приключения. Вы можете продолжить изучения разработки в следующих частях или вы можете ознакомиться с одним из примеров проектов, которые вы можете найти в лаунчере (стартовом экране), чтобы получить еще больше полезных навыков.
UEngine.Ru
Русскоязычное сообщество Unreal Engine 4
Введение в Блупринты
Блупринты являются типом ассетов, которые предоставляют пользователям интуитивную систему для создания специальных типов объектов, которые вследствии можно поставить на сцену. Так же Блупринты используются для создания игровой логики уровня или логики уровня, при этом не написав ни строчки кода, что облегчит написание логики не только программистам, но и дизайнерам, кто не силен в программировании.
В качестве облегчения перевода и узнаваемости, все типы, кнопки, блоки, переменные и так далее, будут написаны на Английском языке.
Как работают Блупринты
Блупринты используют встроенную в редактор систему для визуального построения логических последовательностей. Соеденяя блоки, события, функции и переменные, возможно создать достаточно сложные логические элементы, которые будут создавать геймплей вашей игры.
Основные типы Блупринтов
Два самых используемых типов блупринтов — Level Blueprint и Class Blueprint.
Level Blueprint
Level Blueprint исполняет такую же роль, как и Kismet в UDK, и имеет почти теже возможности. Каждый уровень имеет свой Блупринт уровня. Сам Level Blueprint используется для манипулирования объектами на сцене в процессе игры, так же контролировать Matinee, стриминг уровней, чекпоинты и остальные системы, которые относятся к уровням. Level Blueprint’ы так же могут взаимодействовать с Class блупринтами, которые имеются на сцене.
Class Blueprint
Class Blueprint позволяют создать сложные объекты для последующего размещения на сцене, такие как открывающиеся двери, ящики с предметами, кнопки и т.п. На изображении сверху напольная кнопка и дверь являются разными блупринтами и содержат определенный скрипт для взаимодействия с игроком, проигрывания анимации и звука, открытии дверей и так далее.
В данном случае, нажатие кнопки активирует событие внутри Блупринта дверей, открывая их. С тем же успехом можно сделать взаимодействие любых блупринтов, а так же срабатывания событий не только на игрока, но и на другие объекты или на Level Blueprint. Class Blueprint могут быть полностью индивидуальными, а значит, для их работы не обязательно воздействовать из вне и они могут работать и производить какие-либо действия сами по себе.
Что ещё могут делать Blueprint’ы?
Создавать игрового персонажа
Игровые персонажи тоже являются Классовыми Блупринтами, с помощью которых вы можете создавать все нужные вам элементы и логику вашего будущего персонажа. Вы можете устанавливать параметры камеры, устанавливать управление персонажем, включая мышь и даже сенсорные экраны и создавать вещи, на которые ваш персонаж способен.
При создании Блупринта Персонажа(Character Blueprint), у вас будут уже заготовленные настраевымые свойства для передвижения, прижка, плаванья и падения. Все, что нужно, это добавить управление и определить, как ваш персонаж будет вести себя.
Создавать интерфейс
Интерфейс создается так же с помощью блупринта, похожего на классовый, однако он привязывается к геймплею, что не требует размещения его на уровне.
Вы можете установить Блупринт интерфейса так, что бы он читал переменные из других Блупринтов и отображал с помощью этой информации какие либо вещи, например очки, показатель жизней персонажа, количество имеющихся патронов в запасе и так далее. С помощью HUD(интерфейс) блупринта можно так же создавать кнопки, что бы создавать различного рода меню.
Редактор Блупринтов
Создавая любую логику с помощью Блупринтов, вы будете работать с Редактором Блупринтов. Редакторы бывают различных типов, в зависимости от редактируемого Блупринта. Основной функционал редактора остается везде(Графики, переменные и т.д.), однако некоторые Блупринты, в особенности Level Blueprint не имеют своих свойств или компонентов.
UnrealEd
Изучение Unreal Engine, документация на русском языке
Введение в Blueprints
Система Blueprints Visual Scripting в Unreal Engine – это полноценная система написания скриптов геймплея, в основу которой положена концепция использования интерфейса узлового типа, позволяющая создавать элементы геймплея прямо в Unreal-редакторе. Как и многие распространённые языки скриптования, он используется для определения объектно-ориентированные (OO) классы или объекты в движке. Если вы используете UE4, вы увидите, что объекты, использующие Blueprint, в народе называются просто «Blueprints».
Как работает Blueprints?
В своей базовой форме Blueprints виртуально скриптует дополнения к вашей игре. Сложные элементы геймплея создаются посредством связывания узлов, событий, функции и вариации в единую сеть.
Blueprints использует узловые сетки для реализации различных целей – конструирования объектов, единичных функций и общих событий геймплея, которые специфичны для каждого случая, создаваемого Blueprint — и внедрения нужного поведения и функциональности.
Часто использующиеся типы Blueprint
Самые распространенные типы Blueprint, с которыми вам придется работать – это Level Blueprints (уровни) и Blueprint Classes (классы).
Это всего два из всех доступных типов Blueprints, среди которых также есть Blueprint Macros (макросы) и Blueprint Interfaces (интерфейсы).
Level Blueprint
Level Blueprint играет ту же роль, что Kismet играл в Unreal Engine 3, и имеет те же возможности. Каждый уровень имеет свой собственный уровневый Blueprint, и он может управлять Актерами (Actors), контролировать все, что относится к фильмовой составляющей, используя Matinee Actors, и управлять вещами типа, стримов уровня, чекпоинтов и систем, связанных с уровнем. Level Blueprint также может взаимодействовать с Blueprint Classes, которые находятся внутри уровня, к примеру, читать/настраивать вариации или запускать кастомные события, которые те содержат.
Blueprint Class
Blueprint Classes идеальны для создания интерактивных ассетов, таких, как двери, выключатели, собираемые предметы и объекты разрушаемой среды. На картинке выше кнопка и набор дверей являются отдельными Blueprint, которые содержат необходимые скрипты, отвечающие, если игрок провоцирует определенные события, анимируя их, включая необходимые звуковые эффекты и изменяя их внешний вид (например, когда нажимают на кнопку, она начинает светиться).
В этом случае нажатие кнопки активирует событие внутри Blueprint, отвечающего за дверь, в результате чего она открывается. Но двери также можно с легкостью активировать с помощью другого типа Blueprint или с помощью Level Blueprint-последовательности. Благодаря самозаполняющейся природе Blueprints, их можно создать, просто набросав в уровни, и они будут прекрасно работать с минимумом настроек. Также это значит, что редактирование Blueprint, который используется в проекте, приведет к полному обновлению всех его структур.
Что еще умеет делать Blueprints?
Ниже приведены некоторые примеры того, как и для чего вы можете применить систему Blueprint.
Создание настраиваемых префабов (Prefabs) с помощью скриптов конструирования
В картах Content Examples длинные комнаты, которые содержат каждый пример (картинка сверху) – это отдельно взятый Blueprint, созданный из множества компонентов. Скрипт конструирования Blueprint создает и обслуживает различные Static Meshes (полигональные сетки) и подсветки, согласно параметрам, описанным в Blueprint’s Details panel (панель деталей). С помощью каждой созданной нами картой Content Example мы можете войти в демо-комнату Blueprint, установить значения, отвечающие за ее длину и высоту и количество комнат, которые можно сгенерировать (плюс некоторые другие опции), и в момент получить готовый набор комнат.
Первоначальное создание Blueprint, наподобие этого, может занять довольно много времени, но если вы знаете, что будете часто его использовать, то время, которое вы сэкономите на строительстве уровня и простоте внесения изменений, может нивелировать эту потерю.
Создание играбельного игрового персонажа
Pawns (пешки)- это еще один тип Blueprint Class, с помощью которого вы можете смиксовать вместе все необходимые элементы для создания играбельного персонажа в Blueprint-графе. Вы можете управлять поведение камеры, создавать вводимые события для мышки, контроллера и тач скринов, а также создавать Animation Blueprint- ассеты для управления скелетной сеткой анимации.
Когда вы начнете создавать нового Blueprint-персонажа, то столкнетесь с необходимостью добавления большого количества поведенческих компонентов, нужных для того, чтоб он мог передвигаться по территории, прыгать, плавать, падать, Для этого пригодятся вводимые события, координирующие то, как должен управляться персонаж.
Создание HUD
Скрипт Blueprint также может быть использован для создания игрового HUD, который похож на Blueprint Classes в том плане, что он может содержать событийные последовательности и вариации, но они не добавляются прямо к уровню, а применяются к ассету GameMode вашего проекта.
Вы можете установить HUD, чтоб читать вариации других Blueprints и использовать их для отражения шкалы здоровья, обновлять значение счета, отображать объектные маркеры и т.д. Также возможно использовать HUD для добавления зон поражения к таким элементам, как кнопки, которые можно кликнуть или в случае мобильных игр, получить реакцию на прикосновение к экрану.
Все примеры, описанные выше, существуют в контенте-образце, доступном в UE4, так что если вы хотите получше познакомиться с этими примерами, то их можно найти в Content Examples, в проектах First Person Shooter и Swing Ninja.
Blueprint Редакторы и графы
Разные типы Blueprint-редактора доступны в зависимости от типа Blueprint, над которым вы работаете. Корневая функция большинства Blueprint Editors – это Graph mode (режим графов), с центральным табом Graph, позволяющим разложить сеть вашего Blueprint.