This feature is in an experimental state so you can try it out, provide feedback, and see what we are planning. You cannot publish a project that uses Custom Inventory and Items at this time.
Please keep in mind that we do not guarantee backward compatibility for assets created at the Experimental stage, the APIs for these features are subject to change, and we may remove entire experimental features or specific functionality at our discretion. Check out the list of known issues before you start working with the feature.
This tutorial shows you how to create a custom "item pickup" interactable component that allows players to pick up custom items, and that adds the picked up item to the player's inventory.
Before Your Begin
You should be familiar with UEFN, Scene Graph, and Verse code in order to successfully complete this tutorial.
Set Up Your Project
Follow these steps to set up your project and enable Custom Inventory and Items.
Open UEFN and create a project from any island template. In Island Templates, you can use the Blank project if you want to ensure a flat area to work with. Name your new project, and click Create to open it in the editor.
From the tool bar, click Project and select Project Settings.
Scroll down to the Experimental Access section, and check the box for Custom Items and Inventory.
Write the Verse Code
The interactable_component is a Scene Graph component that is used to handle general interaction. By default, players can press an input to interact with an entity that has the component. Follow these steps to customize this component.
An interactable_component requires an entity to have a mesh_component to interact with. It is necessary for the object to have collision that can be checked against when something is trying to interact with the entity.
Select the entity you are going to add the custom interactable component to. In the Details panel, click +Component and select New Verse Component. The Create Verse Component window opens.
You can also create a Verse component by adding a new Verse file using Verse Explorer.
Under Choose a Template, select Scene Graph Component.
At the bottom, in the Component Name field, type item_interactable_component. Then click Create.
In the menu bar, click Verse > Verse Explorer. Locate your new Verse component, right click it and select Open in Visual Studio Code.
In the new Verse file, delete the existing code, since you are going to write the whole thing in this tutorial. First add the required modules. You can copy and paste them from the snippet below.
Verseusing { /Verse.org/Simulation } using { /Verse.org/SceneGraph } using { /UnrealEngine.com/Itemization }Next, add a helper function to get the root inventory from a specified player.
VerseGetInventoryRoot(Agent:agent)<decides><transacts>:inventory_component = Inventory := (for (I : Agent.FindDescendantComponents(inventory_component)) { I })[0]Before creating the new custom component, you need to declare a new message type constant outside of the scope of our class. This message is the default value if the function is unable to get a name from an item's
item_details_component. Typically this message type is written at the very bottom of the Verse file.VerseDefaultInteractionMessage<localizes>:message = "Interact"Define a new Scene Graph that inherits from the
interactable_component. This is theitem_interactable_component.Verseitem_interactable_component := class(interactable_component) :Add an optional
cancelablevariable. This custom component will need to subscribe to an event to know when a player interacts with the item. This variable saves a reference to that subscription, and will cancel it if needed.Versevar SucceededEventHandler : ?cancelable = falseNext, override the
OnAddedToScenefunction so that it sets the optional variable when the parent of the entity that owns this component changes (such as when it is placed in the world). SetSucceededEventHandlerto call the subscribe function onSucceededEvent. This will also define theOnSucceededEventfunction so that it triggers when interaction occurs.VerseOnAddedToScene<override>():void = if(not SucceededEventHandler?): set SucceededEventHandler = option{SucceededEvent.Subscribe(OnSucceededEvent)}The
SucceededEventsubscription needs to be cleaned up once an item has been picked up, or it might interfere with other code once the item is in an inventory. You can do this by overriding theOnRemovingFromScenefunction. This activates when the parent of the item entity changes. Use it here tocancel()the event subscription. If successful it will also invalidate theSucceededEventHandler.VerseOnRemovingFromScene<override>():void = if(SucceededEventHandler?.Cancel()): set SucceededEventHandler = falseIn step 10 the
OnSucceededEventfunction is subscribed toSucceededEvent, but it doesn't exist in the code yet. So you need to write a new function with the same signature. In step 6, you used the helper functionGetInventoryRoot[]to retrieve the root inventory from the interacting player. Now call theAddItemDistribute()function to provide the entity owning this component.VerseOnSucceededEvent(Agent:agent):void = if(PickupInventory := GetInventoryRoot[Agent]): if(PickupInventory.AddItemDistribute(Entity).GetSuccess[]):The last bit of code needed for this component is the override for the
InteractMessage[]function. This returns the message that is shown onscreen when a player is looking at the item, before they pick it up. This will check the entity owning this component to see if it also has anitem_details_component. If it does, this retrieves the name of the item. Otherwise, if the entity did not have anitem_details_componentor it was removed for some reason, this uses theDefaultInteractionMessagewe declared earlier.VerseInteractMessage<override>(Agent:agent)<reads><decides>:message = if(Details := Entity.GetComponent[item_details_component]): Details.Name else: DefaultInteractionMessage
Setting Up the Prefab
Now that you have written your item_interactable_component, you can make an example item to showcase it. Follow these steps to create a Scene Graph prefab and attach the new component.
Right-click in the Content Browser, and from the context menu select Entity Prefab Definition. Name the new prefab Item_Cube.
Open the new prefab, and add the following components by clicking +Component in the Details panel.
item_componentitem_details_component- fill out the fields in this component:Name
Description
Short Description
mesh_component- select the cube primitive or another cube.item_interactable_component
The video below shows the item_interactable_component in action. When the player interacts with the Item_Cube prefab you created, the item is added to the player's inventory.
Here is the complete script for this tutorial.
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]