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 Virtual Pointer 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.
What is Virtual Pointer?
The Virtual Pointer lets players interact with on-screen elements in a way that works on all supported input devices. The pointer is defined differently depending on the device the player is using:
On touch, this is driven by finger contact.
On mouse and keyboard, this is the existing mouse pointer.
On the controller, this is a virtual on-screen pointer driven by the left stick.
You can use the Virtual Pointer to provide players with a clear, consistent method to point at and interact with things on screen, whether on console, PC, or mobile. This includes interacting with world objects with screen-space deprojection.
Unreal Editor for Fortnite (UEFN) reads the Virtual Pointer as a normal pointer.
This approach keeps gesture-driven input predictable and consistent across platforms, making swipe, and future interactions exist everywhere without designers worrying about device-specific edge cases.
Virtual Pointer does not work when the Fortnite game menus are open.
Enabling Virtual Pointer
For Virtual Pointer to be enabled for use in-game, you must first enable touch mapping with the AddInputMapping method.
You must add your custom input maps to players for any custom input to apply in game.
Enable the Virtual Pointer Mode for a Player
AddTouchMapping(Player:player):void=
if:
PlayerInput := GetPlayerInput[Player]
then:
PlayerInput.AddInputMapping(TouchMapping)
This will add the TouchMapping input mapping to the player, causing the player to enter virtual pointer mode. At this point, players using a gamepad will see the virtual pointer.
Players are immobilized when in Virtual Pointer mode.
Get Screen Space Coordinates
This snippet allows you to capture the screen space coordinates:
var MaybeInputCancelableBegin : ?cancelable = false
StartSubscription(Player:player):void=
if:
PlayerInput := GetPlayerInput[Player]
then:
PlayerInput.AddInputMapping(TouchMapping)
InputCancelableDetectBegin := PlayerInput.GetInputEvents(PointerSelect).BeginDetectEvent.Subscribe(PlayerClicked)
set MaybeInputCancelableBegin = option{InputCancelableDetectBegin}
PlayerClicked(Arg:tuple(player, vector3)):void=
Detect World Objects That Intersect With the Virtual Pointer
World objects that intersect with the Virtual Pointer trace can be detected with Verse:
PlayerClicked(Arg:tuple(player, vector3)):void=
Player := Arg(0)
ClickPos := Arg(1)
Ray := TraceFromClick(Player, ClickPos.Left, ClickPos.Up)
RayOrigin := Ray.Origin
RayDir := Ray.Direction
# Sweep: ray direction * max distance
Displacement := RayDir * 50000.0
Detect Player Swipes
You can use this system to detect when the player swipes their finger in a certain direction on the screen, or takes the equivalent action via gamepad or mouse.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Input }
using { /Verse.org/Input/UI }
using { /Verse.org/SpatialMath }
using { /UnrealEngine.com/Temporary/Diagnostics }
# ============================================================================
# Swipe direction classification
# ============================================================================
Pinch Actions With Virtual Pointer
Pinch actions are a continuous input that can be used for functionality such as camera zoom and object scaling. Pinching is controlled differently depending on the device the player is using:
On touch, Players pinch with two fingers, moving them together or apart. The pinch is centered on the midpoint between the two fingers. Each update produces a value reflecting the speed of the pinch, with 0 meaning no change.
On mouse and keyboard, the scroll wheel produces a value (-1 to 1) based on scroll direction. The pinch is centered on the current Pointer position. The value on a mouse without freewheeling it is -1 or 1. In freewheel mode, it will function more like the right stick.
On controllers, Right stick Up is zoom in, Right stick Down is zoom out. In both cases, the amount of stick deflection from neutral produces a value from -1 to 1. The pinch is centered on the Virtual Pointer’s current position.
Zooming With Pinch
You can enable zoom by subscribing to the PointerZoom Input Event. An example of how to subscribe to the Input Actions of the PointerZoom Input Event and Print to the console when an action is subscribed to is shown below:
EnableCursorZoom(Player : player):void =
if:
PlayerInput := GetPlayerInput[Player]
then:
PlayerInput.AddInputMapping(TouchMapping)
BeginSub := PlayerInput.GetInputEvents(PointerZoom).BeginDetectEvent.Subscribe(OnPinchBegin)
OngoingSub := PlayerInput.GetInputEvents(PointerZoom).DetectionOngoingEvent.Subscribe(OnPinchOngoing)
TriggerSub := PlayerInput.GetInputEvents(PointerZoom).TriggerActivationEvent.Subscribe(OnPinchTrigger)
EndSub := PlayerInput.GetInputEvents(PointerZoom).EndDetectEvent.Subscribe(OnPinchEnd)
Resizing Objects With Pinch
You can use the PointerZoom input event to detect when the player pinches two fingers in a certain direction on the screen, or takes the equivalent action on a gamepad or mouse.
Let’s resize a Scene Graph entity with the pinch action.
To make a simple entity:
Add a blank entity using the toolbar: Place Actors > Entities > entity.
Add a
mesh_componentto the entity by left clicking the + Component button in the details panel and selectingmesh_component.For this example, select Cube as the
mesh_componentsubclass.
For more information on Scene Graph entities and components, see Working with Entities and Components.
Below is an example pinch_scale_device that allows you to grow or shrink the example cube.
Make sure to set PropToScale to our previously made ScalableCube.
# Pinch-to-Scale — Tutorial Device
#
# Pinch on a touchscreen (or mouse-wheel) to grow/shrink a prop in the world.
# Point PropToScale at the SceneGraph mesh entity you want to resize.
using { /Verse.org/Simulation }
using { /Verse.org/SceneGraph }
using { /Verse.org/SpatialMath }
using { /Verse.org/Input }
using { /Verse.org/Input/UI }
Disabling Virtual Pointer
Unsubscribing from the PointerSelect input action will stop the system from getting screen-space coordinates. Additionally, removing the TouchMapping mapping will exit Virtual Pointer mode.
You do not have to unsubscribe from Pointer Select in order to remove TouchMapping .
RemoveTouchInput(Player:player) : void =
if:
PlayerInput := GetPlayerInput[Player]
then:
# Remove touch/pointer input mapping
PlayerInput.RemoveInputMapping(TouchMapping)
Example Verse Code
Here is a complete example of a Verse device that turns on Virtual Pointer mode, subscribes to Pointer Select, and returns world objects that intersect with the Virtual Pointer trace to the world.
using { /Fortnite.com/Devices }
using { /Verse.org/Simulation }
using { /Verse.org/Input }
using { /Verse.org/SpatialMath }
screenspace_trace_device := class(creative_device):
var MaybeInputCancelableBegin : ?cancelable = false
# Runs when the device is started in a running game
For more details about how to add and customize Player input, see How to Add Player Input.