Эта функция находится на этапе экспериментальной версии. Вы можете опробовать её, оставить отзыв и узнать, что мы планируем делать с ней дальше. На данный момент нельзя публиковать проекты, в которых используются пользовательский инвентарь и предметы.
Обратите внимание: мы не можем гарантировать обратную совместимость для ресурсов, созданных на экспериментальном этапе. API для этих функций могут меняться, при этом мы можем полностью удалить экспериментальные функции или отдельные их части по своему усмотрению. Прежде чем приступать к работе с этой функцией, ознакомьтесь со списком известных проблем.
В этом уроке вы узнаете, как создать интерактивный компонент подбора предметов, который позволяет игрокам подбирать пользовательские предметы и добавляет подобранный предмет в инвентарь игрока.
Подготовка
Для успешного прохождения этого обучения вы должны быть знакомы с UEFN, Scene Graph и Verse.
Настройка проекта
Выполните следующие действия, чтобы настроить проект и включить систему пользовательских предметов и инвентаря.
Откройте UEFN и создайте проект из любого шаблона острова. В шаблонах островов можно использовать пустой проект, если вам нужна плоская область для работы. Придумайте название для нового проекта и нажмите «Создать», чтобы открыть его в редакторе.
На панели инструментов нажмите на Проект и выберите Настройки проекта.
Прокрутите вниз до раздела Экспериментальный доступ и установите флажок для параметра Пользовательские предметы и инвентарь.
Написание кода Verse
interactable_component — это компонент Scene Graph, который используется для обработки общего взаимодействия. По умолчанию игроки могут нажимать клавишу ввода, чтобы взаимодействовать с модулем, содержащим этот компонент. Выполните следующие действия, чтобы настроить этот компонент.
Для interactable_component необходимо, чтобы модуль содержал mesh_component для взаимодействия. Это необходимо для проверки включения коллизии у объекта, когда что-то пытается взаимодействовать с модулем.
Выберите модуль, к которому вы хотите добавить пользовательский интерактивный компонент. На панели «Сведения» нажмите «+Компонент» и выберите «Новый компонент Verse». Откроется окно «Создать компонент Verse».
Вы также можете создать компонент Verse, добавив новый файл Verse через проводник Verse.
В разделе Выбрать шаблон выберите Компонент Scene Graph.
Внизу, в поле Название компонента введите item_interactable_component. Затем нажмите «Создать».
В строке меню выберите Verse > Проводник Verse. Найдите новый компонент Verse, нажмите по нему правой кнопкой мыши и выберите Открыть в Visual Studio Code.
В новом файле Verse удалите существующий код, так как в этом уроке вы напишете его полностью. Сначала добавьте необходимые модули. Вы можете скопировать и вставить их из приведённого ниже фрагмента.
Verseusing { /Verse.org/Simulation } using { /Verse.org/SceneGraph } using { /UnrealEngine.com/Itemization }Затем добавьте вспомогательную функцию для получения корневого инвентаря у указанного игрока.
VerseGetInventoryRoot(Agent:agent)<decides><transacts>:inventory_component = Inventory := (for (I : Agent.FindDescendantComponents(inventory_component)) { I })[0]Прежде чем создавать новый пользовательский компонент, вам нужно объявить константу нового типа сообщения за пределами области видимости нашего класса. Это сообщение является значением по умолчанию, если функция не может получить название из элемента
item_details_component. Обычно этот тип сообщения записывается в самом низу файла Verse.VerseDefaultInteractionMessage<localizes>:message = "Interact"Определите новый Scene Graph, который наследует от компонента
interactable_component. Этоitem_interactable_component.Verseitem_interactable_component := class(interactable_component) :Добавьте необязательную переменную
cancelable. Этому пользовательскому компоненту необходимо будет подписаться на событие, чтобы узнать, когда игрок взаимодействует с предметом. Эта переменная сохраняет ссылку на эту подписку и отменяет её при необходимости.Versevar SucceededEventHandler : ?cancelable = falseДалее переопределите функцию
OnAddedToScene, чтобы она задавала необязательную переменную при изменении родительского элемента модуля, которому принадлежить этот компонент (например, при его размещении в мире). ЗадайтеSucceededEventHandlerдля вызова функцииSucceededEvent, на которую можно подписаться. Здесь также будет определена функцияOnSucceededEvent, чтобы она срабатывала при взаимодействии.VerseOnAddedToScene<override>():void = if(not SucceededEventHandler?): set SucceededEventHandler = option{SucceededEvent.Subscribe(OnSucceededEvent)}Подписку на событие
SucceededEventнеобходимо сбрасывать после подбора предмета, иначе она может помешать работе другого кода, когда предмет находится в инвентаре. Ты Это можно сделать, переопределив функциюOnRemovingFromScene. Активируется при изменении родительскоого модуля предмета. Используйте её здесь, чтобы отменить (cancel()) подписку на событие. В случае успешного выполнения это также сделает недействительнымSucceededEventHandler.VerseOnRemovingFromScene<override>():void = if(SucceededEventHandler?.Cancel()): set SucceededEventHandler = falseНа шаге 10 функция
OnSucceededEventподписана наSucceededEvent, но она ещё не существует в коде. Поэтому вам нужно написать новую функцию с той же сигнатурой. На шаге 6 вы использовали вспомогательную функциюGetInventoryRoot[], чтобы получить корневой инвентарь у взаимодействующего игрока. Теперь вызовите функциюAddItemDistribute(), чтобы указать модуль, которому принадлежит компонент.VerseOnSucceededEvent(Agent:agent):void = if(PickupInventory := GetInventoryRoot[Agent]): if(PickupInventory.AddItemDistribute(Entity).GetSuccess[]):Последний бит кода, необходимый для этого компонента, — это переопределение функции
InteractMessage[]. Возвращает сообщение, которое отображается на экране, когда игрок смотрит на предмет, перед тем, как его взять. При этом мы проверим модуль, которому принадлежит компонент, на наличиеitem_details_component. Если есть, то извлекается название предмета. В противном случае, если у модуля не былоitem_details_componentили он был удалён по какой-либо причине, используетсяDefaultInteractionMessage, объявленное ранее.VerseInteractMessage<override>(Agent:agent)<reads><decides>:message = if(Details := Entity.GetComponent[item_details_component]): Details.Name else: DefaultInteractionMessage
Настройка заготовок
Теперь, когда вы написали компонент item_interactable_component, вы можете создать пример предмета, чтобы посмотреть его в действии. Выполните следующие шаги, чтобы создать заготовку Scene Graph и присоединить новый компонент.
Нажмите правой кнопкой мыши в «Каталоге ресурсов» и в контекстном меню выберите Определение заготовки модуля. Назовите новую заготовку Item_Cube.
Откройте новую заготовку и добавьте следующие компоненты, нажав +Компонент на панели Сведения.
item_componentitem_details_component— заполните поля в этом компоненте:Название
Описание
Краткое описание
mesh_component— выберите примитив-куб или другой куб.item_interactable_component
На видео ниже показана работа компонента item_interactable_component. Когда игрок взаимодействует с созданной вами заготовкой Item_Cube, предмет добавляется в инвентарь игрока.
Ниже представлен полный код для этого урока.
using { /Verse.org/Simulation }
using { /Verse.org/SceneGraph }
using { /UnrealEngine.com/Itemization }
# This function returns the first subentity with an inventory_component. Use this to get the root inventory of an agent.
GetInventoryRoot(Agent:agent)<decides><transacts>:inventory_component =
Inventory := (for (I : Agent.FindDescendantComponents(inventory_component)) { I })[0]