Эта функция находится в раннем доступе. Вы можете опубликовать остров с данной функцией, но имейте в виду, что в течение периода раннего доступа изменения могут нарушить работу вашего острова и потребовать активного вмешательства с вашей стороны.
Для генераторов неигровых персонажей требуется дорожка «Время жизни привязки» в Sequencer. Эту дорожку невозможно добавить «задним числом» к существующим последовательностям, созданным до версии 31.00. После добавления дорожек «Время жизни привязки» необходимо повторно опубликовать в последовательности остров, на котором используется генератор неигровых персонажей.
Чтобы добавить дорожку «Время жизни привязки»:
-
Нажмите на значок + рядом с Генератором неигровых персонажей в списке дорожек.
-
Выберите Время жизни привязки из выпадающего меню.
Используйте Sequencer для создания пользовательских анимаций персонажей, которые можно воспроизводить различными способами и на разных устройствах, включая Генератор неигровых персонажей. Используйте либо события, либо Sequencer в паре с устройствами Последовательность внутриигрового видео для настройки и воспроизведения анимаций с шаблонным поведением в выбранных точках маршрута патрулирования ИИ.
Вы можете импортировать и переносить пользовательские анимации из Unreal Engine (UE), включая персонажи MetaHuman. Для этого вам, возможно, придётся перенести скелетную сетку так, чтобы она соответствовала неигровым персонажам, поскольку персонажи Fortnite имеют собственную структуру скелета.
Персонажи MetaHuman расходуют больше памяти. Рекомендуется ограничить количество используемых ресурсов MetaHuman.
Анимация неигровых персонажей в Sequencer
Устройство «Генератор неигровых персонажей» открывает множество творческих возможностей в игре, от интерактивных персонажей до информативных внутриигровых видео. Создавайте пользовательские анимации для генератора неигровых персонажей с помощью Регулятора каркаса или импортируйте анимации, которые вы приобрели или создали в другом ПО.
Вы также можете использовать Регулятор каркаса с прямой кинематикой, чтобы анимировать неигровые персонажи с помощью перенесённой анимации или эмоций.
Узнайте больше о рабочих процессах анимации с использованием Регулятора каркаса с прямой кинематикой в документации UE.
Чтобы создать анимацию с участием неигровых персонажей, выполните следующие действия.
-
Нажмите правой кнопкой мыши в Каталоге ресурсов, чтобы создать видеоряд.
-
Переименуйте миниатюру видеоряда.
-
Дважды нажмите на миниатюру видеоряда, чтобы открыть Редактор Sequencer.
-
Нажмите +Дорожка и выберите Актор в Sequencer > Генератор неигровых персонажей. Так вы добавите устройство «Генератор неигровых персонажей» на дорожку видеоряда.
Вы можете перетащить устройство «Генератор неигровых персонажей» в список дорожек с панели Структура, чтобы добавить его в видеоряд.
-
Нажмите на значок + рядом с устройством «Генератор неигровых персонажей» в списке дорожек и выберите Регулятор каркаса > Классы регулятора каркаса > Регулятор каркаса с прямой кинематикой. Так вы добавите скелет неигрового персонажа на дорожку и сможете управлять отдельными костями скелета и осуществлять запись.
-
Выберите кости, положение которых хотите изменить, в окне просмотра, на вкладке Структура анимации или в Sequencer и установите их в исходное положение для анимации.
-
Добавьте первый опорный кадр, нажав на значок + рядом с костями, которые вы переместили.
Если у вас есть анимация, которую вы создали или приобрели, в виде файла последовательности анимации FBX, вы можете добавить этот файл на дорожку анимации устройства «Генератор неигровых персонажей» на временной шкале, нажав на значок + рядом с генератором и выбрав Анимация > Файл анимации.
Продолжайте изменять положение костей и добавлять новые опорные кадры на временной шкале Sequencer, пока не закончите анимацию. Когда анимация будет готова, воспроизведите её в Sequencer, чтобы убедиться, что всё движется так, как нужно.
Простой способ воспроизвести анимацию в обратном порядке — нажать правой кнопкой мыши на файл анимации на временной шкале и выбрать Свойства > Назад.
Когда результат вас устроит, нужно будет прописать анимацию в скелетной сетке. Нажмите правой кнопкой мыши на генераторе неигровых персонажей и выберите Прописать последовательность анимации.
Убедитесь, что при воспроизведении анимации конечности скелетной сетки не проходят сквозь другие части тела скелетной сетки.
Запись атрибутов поведения
Также для устройства «Генератор неигровых персонажей» вы можете использовать атрибуты поведения. Параметры поведения определяют базовые характеристики, наследуемые неигровыми персонажами от неигровых персонажей из Королевской битвы Fortnite. Эти характеристики определяют, действует ли неигровой персонаж как охранник или как дикое животное.
Для получения подробной информации о том, как задать атрибуты поведения с помощью устройства «Генератор неигровых персонажей», см. документ Определение неигрового персонажа.
После настройки этих атрибутов поведения вы сможете создавать опорные кадры анимации в видеоряде и воспроизводить их на устройстве «Последовательность внутриигрового видео» во время игры. В отличие от действий, описанных выше, вам не нужно прописывать характеристики в Регуляторе каркаса, поскольку поведение задаётся в настройках устройства «Генератор неигровых персонажей».
Вы также можете использовать созданную вами анимацию или унаследованное поведение с помощью устройства «Точка маршрута патрулирования ИИ» и записать неигрового персонажа, следующего по созданному вами маршруту, с помощью актора кинокамеры.
Создаваемые и заменяемые привязки неигровых персонажей
Теперь есть ещё два способа добавлять неигровых персонажей в последовательности: с помощью привязки создаваемого неигрового персонажа и привязки заменяемого неигрового персонажа. Эти привязки можно задать в определении неигрового персонажа.
Привязка создаваемых неигровых персонажей
С помощью последовательности внутриигрового видео привязка создаваемого неигрового персонажа позволяет добавить актор в мир с учётом определения неигрового персонажа. Этого неигрового персонажа можно анимировать в Sequencer так же, как и любую скелетную сетку.
Чтобы создать привязку создаваемого неигрового персонажа, достаточно перетащить определение неигрового персонажа в Sequencer:
Нажмите на gif-изображение, чтобы увеличить его.
Эту привязку можно анимировать, как и любой другой актор скелетной сетки. Пример:
-
Нажмите + Анимация и выберите эмоцию танца для определения неигрового персонажа.
Нажмите на gif-изображение, чтобы увеличить его.
-
Продвиньте указатель воспроизведения ещё вперёд, перетащите своего неигрового персонажа в новое место и задайте новый опорный кадр. Теперь неигровой персонаж переместится из точки A в точку B.
Нажмите на gif-изображение, чтобы увеличить его.
Привязка заменяемого неигрового персонажа
Привязка заменяемого неигрового персонажа будет управлять появляющимся в мире неигровым персонажем и разместит его в вашей последовательности. После этого можно воспроизводить анимации, созданные в Sequencer. Когда неигровой персонаж получает привязку в Sequencer, всё поведение, восприятие и следование по пути приостанавливаются. Они возобновляются, когда привязка у неигрового персонажа убирается.
Неигровой персонаж вернётся на исходное место, когда его привязка будет убрана.
Чтобы создать привязку заменяемого неигрового персонажа, создайте привязку создаваемого неигрового персонажа, нажмите на ней правой кнопкой мыши и выберите Преобразовать выбранную привязку в > Заменяемый неигровой персонаж.
Нажмите на gif-изображение, чтобы увеличить его.
После преобразования дорожка заменяется дорожкой привязки времени жизни. Все изменения, внесённые в создаваемую привязку, сохраняются.
Чтобы неигровой персонаж можно было найти и привязать в процессе игры, необходимо добавить модификатор в определение неигрового персонажа: модификатор Sequencer. Вы можете добавить его к определению неигрового персонажа, используя тот же метод, что используется в других модификаторах. Если вы не добавите этот модификатор, проверка не даст результата.
Нажмите на gif-изображение, чтобы увеличить его.
Модификатор Sequencer имеет свойство Уникальный идентификатор. Это свойство используется для поиска создаваемого неигрового персонажа в игре. Значение по умолчанию — это название определения неигрового персонажа. Обратите внимание, что если два разных определения неигровых персонажей будут иметь одинаковый уникальный идентификатор, при воспроизведении последовательности в игре оба они будут иметь привязку.
Воспроизведение последовательностей в игре
Для воспроизведения последовательностей просто используйте устройство «Последовательность внутриигрового видео».
Создаваемая привязка не требует какой-либо настройки для воспроизведения.
Чтобы использовать заменяемую привязку, нужно добавить в мир генератор неигровых персонажей, который использует ваше определение неигрового персонажа. Если заменяемая привязка не может найти привязываемого неигрового персонажа, вы увидите следующую строку в журнале клиента:
LogFortNPCMовиеSceneBindings: Предупреждение: не удастся выполнить привязку к пешке, используя защиту определения неигрового персонажа. Убедитесь, что есть хотя бы один созданный персонаж.
Если вы хотите создать неигрового персонажа одновременно с воспроизведением последовательности в заданный момент. На устройстве «Последовательность внутриигрового видео» можно либо использовать создаваемую привязку, либо привязать событие при создании к функции Воспроизведения.
Неигровые персонажи с пользовательскими схемами
Большинство типов неигровых персонажей привязываются как скелетная сетка, за исключением определения неигрового персонажа, которое использует пользовательскую схему.
Это приведёт к привязке схемы и открытию дополнительных компонентов, таких как визуальные эффекты, которые затем можно будет изменять в Sequencer.
Здесь вы можете увидеть, что система частиц Niagara была изменена в Sequencer, чтобы голова неигрового персонажа взрывалась:
Нажмите на gif-изображение, чтобы увеличить его.
Известные ограничения
- Привязки заменяемых неигровых персонажей можно использовать только с устройством «Последовательность внутриигрового видео», для которого задан параметр Видимость: все. При использовании любой другой настройки видимости проверка не даст результата.
- Попытка использовать привязку заменяемого неигрового персонажа с дикими животными, пригодными для верховой езды или приручения, не даст результата.
- Привязки заменяемых неигровых персонажей, использующих определение неигрового персонажа, не могут использовать настройку Принудительное сохранение состояния в пользовательском параметре Приоритет перед состоянием завершения. При попытке использовать эту настройку проверка не даст результата.
- Когда неигровой персонаж привязан с помощью Sequencer, он встанет на место. Кроме того, проблемы с задержками могут приводить к кратковременным ошибкам визуализации (багам) при привязке и отсутствии привязки неигрового персонажа. По этой причине при использовании привязки заменяемого неигрового персонажа мы настоятельно рекомендуем использовать такие приёмы, как создание неигрового персонажа за пределами экрана, затухание экрана, визуальные эффекты или дорожка видимости.
Вызов анимаций с помощью Verse
Вы можете воспроизводить пользовательские анимации своих неигровых персонажей с помощью модуля анимации, сделав доступными анимации в Verse с помощью отражения ресурсов.
Интерфейс контроллера анимации
Интерфейс play_animation_controller позволяет воспроизводить анимацию персонажа, и к нему можно получить доступ с помощью функции GetPlayAnimationController(). Этот интерфейс предоставляет две функции, воспроизводящие анимацию. Это синхронная функция Play() и асинхронная функция PlayAndAwait().
Обе функции принимают следующие параметры:
| Параметр | Значение | Описание |
|---|---|---|
| Анимация | Выберите анимацию | Анимация для воспроизведения. Это должна быть анимация из файла Assets.digest.verse Assets.digest.verse. |
| PlayRate | 1,0, Выберите скорость воспроизведения | Скорость воспроизведения анимации. Значение 1,0 соответствует скорости воспроизведения анимации по умолчанию. |
| BlendInTime | 0,0, выберите BlendInTime | Интервал времени перехода от предыдущей анимации к текущей. |
| BlendOutTime | 0,0, выберите BlendInTime | Интервал времени перехода от текущей анимации к следующей. |
| StartPositionSeconds | 0,0 , выберите StartPositionSeconds | Позиция в секундах, с которой нужно начать воспроизведение анимации. |
Функция воспроизведения и ожидания
Функция PlayAndAwait() асинхронно воспроизводит анимацию и возвращает экземпляр перечисления play_animation_result, который содержит одно из трёх значений — Completed, Interrupted или Error. Они соответствуют завершённой анимации, прерванной анимации и ошибке соответственно. Запросив это перечисление, вы можете выполнить другой код в зависимости от результата воспроизведения анимации.
AnimationResult := PlayAnimController.PlayAndAwait(MyAnimation)
case(AnimationResult):
play_animation_result.Completed => Print("Анимация завершена!")
play_animation_result.Interrupted => Print("Анимация прервана.")
play_animation_result.Error => Print("Во время воспроизведения анимации возникла ошибка.")
Функция воспроизведения
Функция Play() выполняется синхронно и возвращает экземпляр класса playing_animation_instance. Класс playing_animation_instance позволяет запросить текущую анимацию и управлять ею; он содержит следующие значения:
| Значение | Пояснение |
|---|---|
| GetState() | Эта функция возвращает текущее состояние воспроизведения анимации в перечислении play_animation_state. |
| Stop() | Эта функция останавливает текущую анимацию. |
| CompletedEvent | Это событие возникает при завершении анимации. |
| InterruptedEvent | Это событие возникает при прерывании анимации. |
| BlendedInEvent | Это событие возникает, когда анимация завершает переход в начале воспроизведения. |
| BlendedOutEvent | Это событие возникает, когда анимация начинает переход в конце воспроизведения. |
| Await() | Эта функция ожидает завершения анимации или её прерывания. Обратите внимание, что она возвращает перечисление play_animation_result и функционально идентична вызову PlayAndAwait(). |
Вы можете использовать функцию Play() для управления текущей анимацией или запуска кода при выполнении определённых условий в анимации.
# Воспроизведём анимацию синхронно и получим её экземпляр
AnimationInstance := PlayAnimController.Play(MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
# Подпишемся на функцию, которая запускается после завершения анимации
AnimationInstance.CompletedEvent.Subscribe(OnAnimationComplete)
Sleep(1.0)
AnimationState := AnimationInstance.GetState()
# Если через секунду анимация ещё воспроизводится, остановим её
if(AnimationState = play_animation_state.BlendingOut):
AnimationInstance.Stop()
Пример воспроизведения анимации
Приведённый ниже код является примером поведения неигрового персонажа, в котором для воспроизведения анимации используется модуль анимации. Обратите внимание, что любые пользовательские анимации, которые вы хотите воспроизвести на своих персонажах, сначала нужно сделать доступными в Verse посредством отражения ресурсов, и они должны появиться в файле Assets.digest.verse Assets.digest.verse. В этом примере анимация MyAnimation находится в модуле Animations пользовательского персонажа MyCharacter в Assets.digest.verse и поэтому вызывается через MyCharacter.Animations.MyCharacter.
using { /Fortnite.com/AI }
using { /Fortnite.com/Animation/PlayAnimation }
using { /Verse.org/Simulation }
using { /Fortnite.com/Characters }
basic_play_anim_example := class(npc_behavior):
# Скорость воспроизведения анимации.
@editable
PlayRate : float = 1.0
# Время перехода от предыдущей анимации
# к текущей.
@editable
BlendInTime : float = 0.25
# Время перехода от текущей анимации
# к следующей.
@editable
BlendOutTime : float = 0.25
# Позиция в секундах, с которой нужно начать
# воспроизведение анимации.
@editable
StartPositionSeconds : float = 0.0
# Время ожидания перед повторным воспроизведением анимации.
@editable
SleepDuration : float = 2.0
OnBegin<override>()<suspends>:void=
if:
# Получим контроллер анимации неигрового персонажа
Agent := GetAgent[]
FortCharacter := Agent.GetFortCharacter[]
PlayAnimController := FortCharacter.GetPlayAnimationController[]
then:
AnimationResult := PlayAnimController.PlayAndAwait(MyCharacter.Animations.MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
# Выведем на экран результат воспроизведения анимации.
case(AnimationResult):
play_animation_result.Completed => Print("Анимация завершена!")
play_animation_result.Interrupted => Print("Анимация прервана.")
play_animation_result.Error => Print("Во время воспроизведения анимации возникла ошибка.")
Sleep(SleepDuration)
# Воспроизведём анимацию синхронно и получим её экземпляр.
AnimationInstance := PlayAnimController.Play(MyCharacter.Animations.MyAnimation, ?PlayRate := PlayRate, ?BlendInTime := BlendInTime, ?BlendOutTime := BlendInTime, ?StartPositionSeconds := StartPositionSeconds)
Sleep(SleepDuration)
AnimationState := AnimationInstance.GetState()
# Выведем на экран текущее состояние анимации.
case(AnimationState):
play_animation_state.Playing => Print("Анимация воспроизводится!")
play_animation_state.BlendingIn => Print("Переход от предыдущей анимации!")
play_animation_state.BlendingIn => Print("Переход к следующей анимации!")
play_animation_state.Completed => Print("Анимация завершена!")
play_animation_state.Stopped => Print("Анимация остановлена!")
play_animation_state.Interrupted => Print("Анимация прервана!")
play_animation_state.Error => Print("Во время воспроизведения анимации возникла ошибка")
else:
Print("Не удаётся получить контроллер анимации")