Verse fields can be defined directly in UMG. Variables are created in a User Widget then bound to widget properties in the Verse code. Variables pass Verse data and are reflected in the asset digest, they also provide a way to create custom dynamic UI without relying on device view models.
In-Island Transactions UI Example
The storefront example expands on the Marketplace API by adding custom UI elements through Verse fields and Verse UI. Data is passed from the API to a data layer, and a Verse class is used to track players and respond to players purchasing objects.
The following files in the template create the look of the custom UI:
shop_setup_device_template- This file defines thevar Shopand calls theShowUIfunction to display the UI coded in theui_shopfile.ui_shop- A class that consolidates all widgets into a Verse file through Verse UI. UMG handles the character image, item details, headers and price, and rows of items. The Verse API handles the background layers and buttons.ui_shop_offer_item- A class to add to the View button of each item row.link_volume_to_shop_device- A device script that uses the Volume device as a trigger to show the shop interface.
Shop UI
The design for the main shop UI is coded in an OverlayRoot. The OverlayRoot uses a material block to call the material instances for the background materials of the Main background and the offer background.
set OverlayRoot = overlay:
Slots := array:
overlay_slot:
Widget := BackgroundWidget
VerticalAlignment := vertical_alignment.Fill
HorizontalAlignment := horizontal_alignment.Fill
overlay_slot:
Widget := CloseButton
Padding := margin {Left := 824.0, Bottom := 30.0}
VerticalAlignment := vertical_alignment.Bottom
A second overlay widget is added which contains a Stack Box. The Stack Box is used to create the body of the offers. The final Stack Box slot is reserved for the OfferDetailsOverlayRoot which is a User Widget that contains the design for the details.
overlay_slot:
Widget := stack_box:
Orientation := orientation.Horizontal
Slots := array:
stack_box_slot:
Widget := stack_box:
Orientation := orientation.Vertical
Slots := array:
stack_box_slot:
Widget := HeaderWidget
PopulateOffers
The PopulateOffers function creates the number of item rows entered for each item listed in the OfferItemWidget creating a repeatable action that works for each offer in the Stack Box. For example, if you have three offers, this function creates three offer widgets for each of your items.
PopulateOffers(InOffers:[]offer) : void =
for (Offer : InOffers):
var OfferItemWidget : ui_shop_offer_item = ui_shop_offer_item {}For each offer, the UpdateSelectedOfferDetails function updates the following data:
Name
Icon
ShortDescription
PriceFloat
UpdateSelectedOfferDetails(SelectedOffer : offer) : void =
var PriceFloat : float = 0.0
if (PriceVB := price_vbucks[SelectedOffer.Price]):
set PriceFloat = GetPriceVBucks(PriceVB)
The HandleBuyButtonClicked method sends the player into the Epic Games payment workflow when the player makes a purchase.
HandleBuyButtonClicked(SelectedOffer : offer) <suspends> : void =
BuyButton.OnClick().Await()
if (PlayerUI := GetPlayerUI[Player]):
HideUI(PlayerUI)
BuyOffer(Player, SelectedOffer)
Device Trigger
In this example, a Volume device is used as a trigger to open the shop UI. You can use any device as a substitute trigger. Or no device at all. Players can approach items individually and the UI will pop-up.
# A Verse-authored creative device that can be placed in a level
link_volume_to_shop_device := class(creative_device):
@editable
var ShopTemplate:shop_setup_device_template = shop_setup_device_template{}
@editable
var OfferVolume:volume_device = volume_device{}