Введение

Последний пост оставил вам плагин Unreal, который включает части AWS sdk, но есть еще много работы, которую нужно сделать, если вы хотите предоставить sdk для чертежей. Предоставление этой функциональности схемам может сделать SDK доступными для более широкого круга разработчиков и проектов. Чтобы понять некоторые детали реализации, полезно немного познакомиться с открытием C ++ для чертежей. В этом сообщении в блоге я расскажу об одной из старейших функций AWS для blueprint, загрузив файл с S3.

ПРИМЕЧАНИЕ. Завершенный проект можно найти здесь

Использование документации AWS

Лучшее место, чтобы узнать, что доступно в каждом SDK, - это документация по C ++, предоставленная AWS.

Настраивать

Мы будем использовать Unreal 4.22 в Windows и начнем с простого примера C ++ от третьего лица. Хотя этот пример не является проектом VR, точно такой же процесс можно выполнить в проекте Unreal, который настроен для развертывания на мобильных гарнитурах Oculus. Уже существует множество хороших руководств о том, как настроить проект Unreal для развертывания на устройствах Oculus. Единственный дополнительный шаг, который может потребоваться, - это убедиться, что у вас есть проект C ++, а не только проект.

Шаг 1. Откройте наш класс C ++ для чертежей

Нам нужно создать способ для наших чертежей получить ссылку на наш класс C ++, чтобы он мог использовать эту функциональность. Я предпочитаю делать это с помощью статической функции, которая возвращает указатель на экземпляр нашего класса C ++. Для нашего AWSS3Client это будет выглядеть так:

Мы можем вызвать эту функцию из любого чертежа, чтобы получить экземпляр нашего класса C ++.

Шаг 2. Получите экземпляр клиента AWS

Для большинства SDK вы можете найти большинство функций, которые вам нужны в клиентском объекте для SDK, который вы используете, поэтому для S3 это страница. В первую очередь следует обратить внимание на конструктор клиентского объекта AWS S3. В нем много всего, что не нужно настраивать. В большинстве случаев ваш конструктор клиента AWS sdk должен выглядеть так.

Aws::S3::S3Client* S3Client (const Aws::Auth::AWSCredentials &credentials, const Aws::Client::ClientConfiguration &clientConfiguration=Aws::Client::ClientConfiguration)

Наш UAWSS3ClientObject создаст ссылку на клиент AWS S3 и будет использовать ее для выполнения всех вызовов службы S3, поэтому давайте создадим частную переменную, которая будет содержать эту ссылку в нашем AWSS3ClientObject.h. Кроме того, давайте обновим нашу функцию CreateS3ClientObject, чтобы она принимала необходимые входные данные для создания клиентского объекта AWS. Я уже создал доступные для чертежей версии объектов Aws :: Auth :: AWSCredentials и Aws :: Client :: ClientConfiguration в модуле AWSBase. Новая функция-конструктор должна иметь эту подпись, и реализация будет следующей:

Шаг 3. Напишите функцию для загрузки файла

Из документации мы видим, что функция загрузки объекта имеет подпись:

virtual Model::GetObjectOutcome GetObject (const Model::GetObjectRequest &request) const

Глядя на документацию для Model :: GetObjectRequest, нам понадобится сегмент S3 и значение ключа, чтобы определить, какой объект загружать. Мы можем создать вокруг этого функцию-оболочку, которая берет информацию, необходимую для создания Model :: GetObjectRequest, и местоположение в локальной файловой системе для размещения загруженного объекта.

Шаг 4. Реализуйте это в схемах

В своем проекте Unreal создайте новый класс актера и добавьте его на уровень от третьего лица. Затем добавьте эту логику проекта в узел начала воспроизведения актера.

ПРИМЕЧАНИЕ. Вы должны быть очень осторожны при передаче этого или любых будущих чертежей в общедоступный элемент управления исходным кодом, такой как GitHub, потому что он имеет ваши учетные данные AWS !!!

Затем измените параметры того объекта, который вы хотите загрузить, и попробуйте!

Проблемы с этой простой реализацией

Несмотря на то, что эта демонстрация отвечает требованиям использования AWS S3 для загрузки объекта, для того, чтобы она стала эффективным инструментом, все же требуется дополнительная работа. Основная проблема заключается в том, что наша функция выполняет блокирующий вызов для загрузки объекта из S3, что означает, что узел Get Object blueprint не вернется, пока объект не будет загружен и записан в вашу файловую систему. В моей небольшой демонстрации это не было проблемой, но это быстро станет проблемой, если вы попытаетесь загрузить файл большего размера, поскольку любая логика после этого вызова Get Object будет отложена. В более общем случае использования любого сервиса AWS вы не хотите, чтобы ваш основной игровой поток блокировался при вызовах сети AWS, поскольку это может вызвать непредсказуемые задержки и может повлиять на FPS вашей игры. К счастью, AWS sdk предоставляет асинхронные версии большинства функций, которые мы можем объединить с системой делегирования Unreal для эффективных вызовов AWS.

Шаг 5. Сделайте вызов Get Object A синхронным.

Большинство функций в SDK AWS имеют асинхронные версии, которые обрабатывают разгрузку сетевых вызовов другому потоку и вызывают функцию обратного вызова, когда доступны результаты. Асинхронная версия GetObject выглядит так:

virtual void GetObjectAsync (const Model::GetObjectRequest &request, const GetObjectResponseReceivedHandler &handler, const std::shared_ptr< const Aws::Client::AsyncCallerContext > &context=nullptr)

Как и блокирующий вызов, он принимает объект Model :: GetObjectRequest, но также принимает GetObjectResponseReceivedHandler, который является указателем на статическую функцию со следующей сигнатурой:

typedef std::function<void(const S3Client*, const Model::GetObjectRequest&, Model::GetObjectOutcome, const std::shared_ptr<const Aws::Client::AsyncCallerContext>&)>

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

Все асинхронные вызовы AWS имеют в подписи объект Aws :: Client :: AsyncCallerContext. Этот объект позволяет вам присоединить UUID к вызову, который будет использоваться, чтобы помочь идентифицировать вызов, когда результаты будут возвращены в функции обратного вызова. Для этого вызова уникальный вызов для получения объекта можно рассматривать как тройку {bucket, key, destination}, поэтому мы объединяем эти значения с помощью «:» в качестве разделителя для разделения значений. Мы возвращаем UUID, чтобы план мог использовать его позже для идентификации возвращаемых объектов.

После реализации этих функций вы сможете вызвать узел чертежа GetObjectAsync и загрузить свой файл, не блокируя основной поток игры!

К сожалению, есть еще что-то, что нужно добавить, потому что теперь наш план не знает, был ли вызов успешным или когда он завершился.

Шаг 6. Добавьте в Unreal Delegate System

Система делегирования Unreal может использоваться для создания асинхронных событий в схемах. Мы можем создать делегата, к которому могут быть привязаны схемы элементов, добавив следующий код в заголовок UAWSS3ClientObject перед объявлением класса.

DECLARE_DYNAMIC_MULTICAST_DELEGATE_OneParam(FObjectReturned, FS3ObjectResult, result);

Чтобы помочь с передачей информации обратно в структурированной форме, мы создали Ustruct, который представляет возвращенные данные.

Затем мы создаем публичный экземпляр этого делегата в нашем объявлении класса:

В нашем проекте мы теперь можем привязать события к этому делегату:

Теперь все, что нам нужно сделать, это сделать широковещательный вызов для нашего делегата, чтобы связанные с ним события уведомлялись о возвращенном вызове из AWS, но снова возникает другая проблема. Делегат будет членом экземпляра UAWSS3ClientObject, но UAWSS3ClientObject :: GetObjectAsync_Handler является статической функцией, поэтому у него нет доступа ни к каким переменным экземпляра. Чтобы обойти это, мы сохраним статический TMap UUID для делегата, который ему нужно вызвать, который выглядит так:

Окончательный чертеж теперь будет выглядеть так:

Последние мысли

Мы надеемся, что эти сообщения в блоге были полезны для демонстрации того, как интегрировать AWS в проект Unreal. Это ни в коем случае не полный проект, поскольку еще предстоит проделать большую работу, чтобы сделать реализации более стабильными, например, надлежащую обработку ошибок. Если у вас есть какие-либо проблемы с проектом, не стесняйтесь оставлять здесь комментарии или поднимать вопросы в репозитории GitHub, и мы постараемся сделать все, чтобы их решить. Мы хотим продолжить работу над генератором плагинов и реализациями SDK, поэтому вам рекомендуется расширять то, что здесь представлено, и делать запросы на вытягивание в репозитории. Любые прямые вопросы, комментарии или проблемы можно направлять по адресу [email protected]. Мы с нетерпением ждем крутых впечатлений от Unreal, созданных с помощью AWS!