HomeSystem plugins › AFS_Core_Pawn
System

AFS_Core_Pawn

The VR, desktop and mobile pawns, motion controllers, hand animation, touch input, and the C++ hand-tracking and gesture system with its Hand Pose Studio editor.

What it gives you

  • Three pawn families in Pawn and Character variants
  • Motion controller actors with per-hand abilities
  • Hand tracking, gesture recognition and synthetic input keys
  • Hand Pose Studio for authoring grip poses

Requires

AFM_Abilities AFM_AutoDestroy AFM_Replication AFM_Teleport AFS_Libraries

Engine: OpenXR OpenXRHandTracking

Required by

AFE_Showroom AF_Examples

21 assets98 API members

Description

This plugin provides the player. Three pawn families — VR, desktop and mobile — each in a plain Pawn and a Character variant, so you can choose between simple movement and full character movement without changing anything else.

The VR pawn spawns its motion controllers as actors rather than components, attached to a CameraHandle that sits between the actor root and the camera. That separation is what makes room-scale work: the capsule can be recentred under the player's head and its height adjusted to the real player without dragging the tracked camera with it.

Hand tracking is handled in C++. Gestures are described declaratively as data assets — finger curl ranges, bone distances, bone angles, a hold time and a priority — and when one is recognised the plugin injects a synthetic input key. That means gestures bind in Enhanced Input exactly like a controller button, and no ability needs to know gestures exist.

Setup

  1. Enable AFS_Core_Pawn. OpenXR and OpenXR Hand Tracking are enabled with it.
  2. Subclass the pawn you need — start from BP_Pawn_VR_Char_Showroom rather than the raw BP_Pawn_VR_Char, since the showroom variant already has the common abilities attached.
  3. On the VR pawn, set Left Controller and Right Controller to the motion controller classes you want. AFE_Showroom ships controller-mesh and hand-mesh variants of each.
  4. Assign your pawn classes in the level's PDA_Level.
Assigning motion controller classes on the VR pawn
AFS_Core_Pawn_setup.pngAssigning motion controller classes on the VR pawn
Assigning motion controller classes on the VR pawn
Tip

With no headset connected the VR pawn still spawns its controllers, pinned to fixed offsets in front of the camera. This keeps VR code paths exercised when you test in a flat editor window.

Usage

Choosing which pawn spawns

You do not choose in the level — you choose in the PDA_Level data asset. Leave Pawn Select on Dynamic and the framework detects headset, then mobile platform, then falls back to desktop.

Adding an ability to a hand

Add a BPC_ControllerAbility subclass to the motion controller Blueprint, not to the pawn. It receives its pawn, controller and side through InitiateControllerAbility.

Recentring the capsule after movement

Call Interface_RecenterCapsule on the pawn. Locomotion already does this; call it yourself if you move the player by other means.

Defining a gesture

Create a UAFSHandGestureDefinition data asset. Add finger curl rules, bone distance rules and bone angle rules — all must pass simultaneously. Set Min Hold Time to avoid flicker and Priority to resolve overlaps. Assign the left and right input keys, then bind those keys in your input mapping context.

A gesture definition with curl and distance rules
AFS_Core_Pawn_gesture_dataasset.pngA gesture definition with curl and distance rules
A gesture definition with curl and distance rules

Authoring a hand pose

Use Hand Pose Studio — see Author a hand pose.

Key properties

PropertyOnWhen to change
Left Controller / Right ControllerBP_Pawn_VRTo swap between controller meshes and hand meshes, or to your own
HMDBP_Pawn_VRRarely; set automatically from the runtime
Trace DistanceBPC_Input_TouchTo change how far mobile touch input reaches
Min Hold TimeGesture definitionRaise if a gesture flickers on and off
PriorityGesture definitionRaise when two gestures can both match the same hand shape

Extending

Derive from a pawn, implement BPI_PawnInfo, and return the right E_Pawn_Type. Assign it in PDA_Level and the rest of the framework adapts.

To add a new gesture, create a data asset — no code. To add a new synthetic key, extend FAFSGestureInputKeys in C++ and register it during module startup.

Performance notes

Performance

The VR pawn's AutoAdjustCapsuleHeight polls on a 0.5 s loop rather than ticking. Gesture evaluation runs per hand per frame while hand tracking is active — if you define many gestures, use Priority and Min Hold Time to keep the matching set small.

Example map

Map_Examples_Interaction_Hands demonstrates hand tracking, custom poses and gesture-driven interaction.

Troubleshooting

The player spawns at floor height. The pawn is the plain Pawn variant where the Character variant was expected, or teleport location correction is not being applied.

Hands do not appear. The motion controller classes are not assigned on the pawn, or OpenXR Hand Tracking is not enabled.

A gesture never fires. Its rules cannot all be satisfied simultaneously — widen a curl range first, since those are the most commonly over-tightened.

API reference

Every blueprint asset in this plugin. Expand an asset to see its members.

AnimBP

ABP_Hand9 members
extends AnimInstance · implements BPI_AnimBP_Hand
KindNameSignatureDescription
eventBlueprintInitializeAnimation()Asks the owning motion controller which hand it is and sets the mirror flag from the answer. The source animations are all right-handed, so the left hand is mirrored through the hand mirror table; a controller that does not report a side leaves the hand unmirrored.
eventBlueprintUpdateAnimation(DeltaTimeX: float)Deliberately empty. Every pose value is pushed in from the motion controller through the hand animation interface rather than pulled each frame, so there is nothing to do per tick.
eventHand_SetHandValue_Index(IsPointing: bool)Points or unpoints the index finger, easing the point blend towards its new weight instead of snapping. Only the index metacarpal chain is affected, so it layers over whatever grip or custom pose is playing.
eventHand_SetHandPose(HandPose: AnimSequenceBase)Plays a custom pose over the whole hand, fading it in over roughly a fifth of a second. Pass an empty sequence to fade back to the driven finger poses.
eventHand_SetHandValue_Thumb(IsThumbUp: bool)Raises or lowers the thumb, easing the thumb blend towards its new weight. Only the thumb chain is affected, so it combines with pointing and gripping.
eventHand_SetHandValue_GripAxis(Axis: float)Curls the whole hand towards the grasp pose by the given amount, 0 for open and 1 for closed. Interpolated at roughly twice the speed of the pointing and thumb blends so squeezing feels immediate.
eventHand_SetHandTracking(Set: bool)Fades between the driven finger poses and the control rig pose fed by the tracked joint transforms. Turning it on without also supplying joint transforms leaves the hand in its reference pose.
eventHand_SetHandValue_TriggerAxis(Axis: float)Curls the index finger by the analogue trigger amount, 0 to 1, easing towards the new value at the same speed as the grip axis. Independent of the pointing blend, which drives the same finger from a boolean.
eventHand_HandTrackingTransforms(ref const Transforms: Transform[])Stores the tracked hand joint transforms, in space relative to the hand mesh, for the control rig to read. Applied without smoothing and only visible while hand tracking is blended in.

Blueprints/Desktops

BP_Pawn_Desktop6 members
extends Character · implements BPI_Trace, BPI_PawnInfo, BPI_AbilityRestriction
KindNameSignatureDescription
fnResetTraceTimer()Internal handler that marks the cached trace stale so the next Get Latest Trace runs a fresh line trace. Fired by a timer set to the trace refresh interval rather than called directly.
eventInputKey_AnyKey_Pressed(Key: Key)Watches every key press and drops the pawn back into Game Only control as soon as a gamepad key is used, hiding the mouse cursor. Keyboard and mouse presses are ignored.
eventInterface_setScreenControlMode(ScreenControl: E_ScreenControlMode)Switches between Game Only, Game And UI and UI Only: stores the mode, recentres the mouse, shows the cursor for the two modes that need it and applies the matching input mode to the player controller. Does nothing when there is no local player controller.
eventsetAbilityRestriction(AbilityTag: name, Set: bool, Reason: name)Adds or removes a named blocker on every pawn ability carrying the given tag, so a whole class of ability can be suppressed at once. Several reasons can be held at the same time; the ability returns only when all are released.
eventClient_Possessed(NewController: Controller)Called on the owning client once the pawn has a controller. Waits until the pawn really is locally controlled, adds the desktop input mappings, applies the current screen control mode, puts the crosshair on screen and hands the pawn to every pawn ability.
eventClient_Unpossessed(OldController: Controller)Called on the owning client when the pawn loses its controller. Removes the desktop input mappings, unpossesses every pawn ability and takes the crosshair off screen.
BP_Pawn_Desktop_Char0 members
extends BP_Pawn_Desktop

No editor-visible members; this asset configures defaults only.

Blueprints/Mobile

BP_Pawn_Mobile5 members
extends Character · implements BPI_AbilityRestriction, BPI_Trace, BPI_PawnInfo
KindNameSignatureDescription
eventsetAbilityRestriction(AbilityTag: name, Set: bool, Reason: name)Adds or removes a named blocker on every pawn ability carrying the given tag. Several reasons can be held at once; the ability returns only when all of them are released.
eventOnSwipeUpdate_Interpolated(Index: ETouchIndex, Delta: Vector2D)Turns a smoothed swipe of the first finger into look input, feeding the horizontal and vertical deltas into yaw and pitch inverted and heavily scaled down. Bound to the touch component; swipes by any other finger are ignored.
eventClient_Possessed(NewController: Controller)Called on the owning client once the pawn has a controller. Waits until the pawn really is locally controlled, adds the mobile input mappings and hands the pawn to every pawn ability.
eventClient_Unpossessed(OldController: Controller)Called on the owning client when the pawn loses its controller. Removes the mobile input mappings and unpossesses every pawn ability.
eventOnOneFingerDoubleTab(ScreenLocation: Vector2D)Teleports the character to whatever the last touch trace hit, provided the trace blocked and the surface is within 30 degrees of level, so walls and steep slopes are refused. Bound to the touch component's one-finger double tap.
BP_Pawn_Mobile_Char0 members
extends BP_Pawn_Mobile

No editor-visible members; this asset configures defaults only.

Blueprints/VR

BP_Pawn_VR11 members
extends Character · implements BPI_Pawn_VR, BPI_PawnInfo, BPI_AbilityRestriction
KindNameSignatureDescription
fnSetupMotionControllerControls(MotionControllerClass: Class<BP_MotionController>, Side: E_Side = "Left")Replaces the hand on one side: destroys the controller already registered there, then spawns the given class attached to the camera handle with the pawn, headset type and side already filled in. Passing no class leaves that side empty.
fnCorrectPawnPositionPawn(InVector: Vector = "0, 0, 0", InRotation: Rotator = "0, 0, 0", UseRotation: bool = false, out Location: Vector, out Rotation: Rotator)Returns the actor location and rotation needed to put the headset, rather than the capsule, at the position you ask for. Only the horizontal offset between capsule and camera is removed, so height is left alone; with Use Rotation on, the supplied rotation is corrected by the player's current head yaw as well.
fngetFocussedComponentDebug(out SceneComponent: SceneComponent)Debug stub with no implementation behind it. Always returns nothing, whatever the move focus setting.
eventSwitchControllers(LeftController: Class<BP_MotionController>, RightController: Class<BP_MotionController>)Swaps both hands at once, destroying whatever is there and spawning the two given classes for left and right. Use it to move between hand meshes and controller meshes at runtime.
eventServer_PrepareVRPawn(HMD: E_HMD)Records which headset the player is on, replicating it to the hands, and then spawns the left and right controllers configured on the pawn. Called from Client Possessed once the pawn is locally controlled.
eventAutoAdjustCapsuleHeight(Set: bool)Starts a twice-a-second loop that resizes the capsule to match the player's head height, clamped between 40 and 300 centimetres, and shifts the actor and camera handle by the same amount so the view does not jump. Only corrects drifts of 15 centimetres or more; pass false to end the loop.
eventInterface_RegisterControllerToVRPawn(MotionController: BP_MotionController, Side: E_Side)Records a newly spawned motion controller against its hand side so the pawn can reach it later. When no headset is enabled it also parks the controller at a fixed offset in front of the camera and clears its motion source, which is what makes the hands visible when previewing in a flat window.
eventsetAbilityRestriction(AbilityTag: name, Set: bool, Reason: name)Adds or removes a named blocker on every pawn ability carrying the given tag, and on every matching controller ability on both hands. Use it to suppress a capability across the whole pawn rather than hand by hand.
eventInterface_RecenterCapsule()Moves the capsule horizontally under the headset and pulls the camera handle back by the same amount, so collision follows the player around the play space without the view shifting. Called by teleport and locomotion after they move the pawn.
eventClient_Possessed(NewController: Controller)Called on the owning client once the pawn has a controller. Waits until the pawn really is locally controlled, prepares the VR pawn and spawns the hands, forces Game Only input with the cursor hidden, sets the spectator screen to a single cropped eye and hands the pawn to every pawn ability.
eventClient_Unpossessed(OldController: Controller)Called on the owning client when the pawn loses its controller, and unpossesses every pawn ability. The spawned hands are left alone; destroy them yourself if the pawn is to be reused.
BP_Pawn_VR_Char0 members
extends BP_Pawn_VR

No editor-visible members; this asset configures defaults only.

Blueprints/VR/MotionControllers

BP_MotionController6 members
extends Actor · implements BPI_MotionController
KindNameSignatureDescription
varPawnInternalPawnOwning VR pawn, handed over on spawn. Used to tell whether this hand belongs to the locally controlled player, so replicated hands do not run local-only logic.
varHMDInternalE_HMDHeadset family this hand was spawned for, taken from the pawn. Hand controllers use it to pick the mesh offset that suits the physical controller, since each one sits differently in the palm.
varSideInternalE_SideWhich hand this is, Left or Right, fixed at spawn by the pawn. Abilities read it through Get Motion Controller Side to choose their input mappings, grip sockets and mirrored hand poses.
eventSetMeshVisibility(Set: bool)Broadcasts Mesh Visibility Changed with the requested state. Nothing is hidden here; the derived controller listens for the broadcast and hides its own mesh, so an ability can ask for the hand to disappear without knowing what it looks like.
eventSetupMotionController()Empty hook left for a derived controller to do its own setup after being spawned and given its pawn, side and headset type. Neither shipped controller uses it.
eventMC_SetFocusControllerAbility(ControllerAbility: BPC_ControllerAbility, Set: bool)Gives one controller ability exclusive use of this hand by blocking every other ability on it under the Unfocussed reason. Passing false releases that blocker again; abilities call it themselves when they take and give up focus.

Blueprints/VR/MotionControllers/Controller

BP_MotionController_Controller4 members
extends BP_MotionController
KindNameSignatureDescription
fnSetControllerMesh(ControllerMaterial: MaterialInterface, LeftControllerMesh: StaticMesh, RightControllerMesh: StaticMesh)
eventChangeControllerMesh(OpenXR: bool, CustomHMD: E_HMD)
eventSetupMotionController()
eventMC_SetControllerVisibility(const Set: bool)
BP_MotionController_Controller_Left0 members
extends BP_MotionController_Controller

No editor-visible members; this asset configures defaults only.

BP_MotionController_Controller_Right0 members
extends BP_MotionController_Controller

No editor-visible members; this asset configures defaults only.

Blueprints/VR/MotionControllers/Hand

BP_MotionController_Hands13 members
extends BP_MotionController · implements BPI_MotionController_Hands
KindNameSignatureDescription
fnDrawHandtrackingDebugHand Tracking()
fnUpdateHandTrackingMeshHand Tracking()
eventSetupMotionController()
eventServer_SnapToSocket(SnapSocket: ST_Socket)
eventServer_SetPose(GrabPose: AnimSequenceBase)
eventMCHands_SnapToSocket(Socket: ST_Socket)
eventMCHands_SetHandCollision(Collision: ECollisionEnabled)
eventServer_GribAxis(GribAxis: float)
eventServerSetThumbDown(ThumbDown: bool)
eventServer_SetIndexDown(IndexDown: bool)
eventMCHands_SetPose(HandPose: AnimSequenceBase)
eventCheckHandTracking()
eventServer_TriggerAxis(TriggerAxis: float)
BP_MotionController_Hands_Left1 members
extends BP_MotionController_Hands
KindNameSignatureDescription
fnMCHands_getGrabWorldTransform(out Transform: Transform)
BP_MotionController_Hands_Right1 members
extends BP_MotionController_Hands
KindNameSignatureDescription
fnMCHands_getGrabWorldTransform(out Transform: Transform)

Components

BPC_Input_Touch22 members
extends ActorComponent
KindNameSignatureDescription
varMaxTapTimeSettingsfloatLongest a finger may stay down, in seconds, and still be classified as a tap rather than a hold. Raise it if short deliberate presses are being missed.
varMaxDoubleTabTimeSettingsfloatWindow in seconds after a tap in which a second tap counts as a double tap. The single tap is broadcast immediately either way, so a double tap fires both the single and the double delegate.
varSwipeSensitivityThresholdSettingsfloatDistance in screen pixels a finger must travel before the touch is reclassified from a tap to a swipe. Lower values make swiping easier to trigger at the cost of losing taps to small wobbles.
varSwipeInterpolationSpeedSettingsfloatSmoothing speed applied to the swipe delta before it is broadcast through On Swipe Update Interpolated, which is what the mobile pawn steers its camera with. Higher values track the finger more closely and jitter more.
varHoldTimeSettingsfloatSeconds a finger must remain down before the touch is treated as a hold rather than a tap.
varUseTraceTraceboolWhether a world trace is run under the first finger on press and on tap. Switch it off to save the trace, but Get Latest Trace then never refreshes and anything that reads it, such as double-tap teleport, stops responding.
varTraceHitDistanceTracefloatHow far into the world the touch trace reaches from the camera, in centimetres. Surfaces beyond it are never reported as a hit.
fnTouchPressedTouch(ref const Index: ETouchIndex, TouchLocation: Vector)Starts tracking a finger: records its location as both the current and the initial position, zeroes its duration and delta, classifies it as a tap for now, and raises Event Touch Pressed. Call it from the pawn's touch input binding.
fnTouchMovedTouch(ref const Index: ETouchIndex, TouchLocation: Vector)Updates the stored screen position for a finger and raises Event Touch Moved. The delta and the tap or swipe classification are worked out on tick, not here.
fnTouchReleasedTouch(ref const Index: ETouchIndex, TouchLocation: Vector)Ends tracking of a finger: raises Event Touch Released with the duration it was held, which is where taps, swipes and drags are dispatched, and then clears every map entry for that index.
fngetAngleAndDegreeUtil(InitialVector: Vector2D, EndVector: Vector2D, IntervalSize: int, out Angle: float, out Index: int)Returns the direction from one screen point to another as an angle in degrees, wrapped to 0-360. The interval index is meant to bucket that angle into equal segments, but the division is inverted, so it comes back as zero for any interval size below a full turn.
fngetTouchLocationsGetter(ref const Index: ETouchIndex, out Found: bool, out Location: Vector2D)Returns the latest screen position of a finger, with Found telling you whether that finger is being tracked at all. Location is meaningless when Found is false.
fngetTouchInitialLocationGetter(ref const Index: ETouchIndex, out Location: Vector2D)Returns the screen position at which a finger first went down, which is the anchor a swipe or drag is measured from. Comes back as zero once that finger has been released.
fngetTouchDeltaGetter(ref const Index: ETouchIndex, out Delta: Vector2D)Returns how far a finger has moved since the last update, in screen pixels. Left at zero for a finger that is not being tracked.
fngetTouchDurationGetter(ref const Index: ETouchIndex, out Duration: float)Returns how long a finger has been held down, in seconds, counted from the moment it was pressed. Comes back as zero for a finger that is not being tracked.
fngetTouchFunctionGetter(ref const Index: ETouchIndex, out Function: E_Touch_Function)Returns what a finger is currently being treated as, tap, swipe or drag. Every touch starts as a tap and is reclassified as it moves; an untracked index reports None.
fnisAnyOtherFingerTabbing(IgnoreIndex: ETouchIndex = "Touch1", out Found: bool, out FoundIndex: ETouchIndex)Returns the first finger other than the one you pass in that is still classified as a tap. Used on release to tell a two-finger tap from a one-finger tap; Found is false when no other finger is down.
fnClearIndex(ref const Index: ETouchIndex)Forgets a finger entirely, removing its location, initial location, delta, duration and classification. Called on release, and also on the partner finger of a two-finger tap so it cannot fire a second time.
eventEventTouchPressed(TouchIndex: ETouchIndex, ScreenLocation: Vector2D)Raised by Touch Pressed once the finger has been recorded, and refreshes the world trace under it. Bind to it to react to a finger going down before it has been classified.
eventEventTouchReleased(TouchIndex: ETouchIndex, ScreenLocation: Vector2D, Duration: float)Raised by Touch Released and does the actual gesture dispatch. A tap becomes a one- or two-finger single or double tap, broadcasts the matching delegate and pulses a synthetic input key for a twentieth of a second; a swipe broadcasts On Swipe End; a drag broadcasts On Drag Release.
eventEventTouchMoved(TouchIndex: ETouchIndex, ScreenLocation: Vector2D)Raised by Touch Moved after the finger's stored position has been updated. Empty by default; bind to it to react to finger movement without polling.
eventUpdateTrace(Index: ETouchIndex, ref const ScreenPosition: Vector2D)Line traces from the given screen position into the world on the visibility channel and stores the result as the latest trace, which the mobile pawn hands out through Get Latest Trace. Only the first finger traces, and only while Use Trace is on.

Interfaces

BPI_AnimBP_Hand7 members
extends Interface
KindNameSignatureDescription
fnHand_SetHandValue_IndexHandAnimBP(IsPointing: bool)Implemented by the hand's animation blueprint to point or unpoint the index finger. Called by the hand motion controller when the pointing state changes or replicates in.
fnHand_SetHandValue_ThumbHand Anim BP(IsThumbUp: bool = false)Implemented by the hand's animation blueprint to raise or lower the thumb. Called by the hand motion controller when the thumbs-up state changes or replicates in.
fnHand_SetHandValue_TriggerAxisHand Anim BP(Axis: float = 0)Implemented by the hand's animation blueprint to curl the index finger by the analogue trigger amount, 0 to 1. Called by the hand motion controller as the trigger moves.
fnHand_SetHandValue_GripAxisHand Anim BP(Axis: float = 0)Implemented by the hand's animation blueprint to close the hand by the analogue grip amount, 0 for open and 1 for a full grasp. Called by the hand motion controller as the grip moves.
fnHand_SetHandTrackingHand Anim BP(Set: bool)Implemented by the hand's animation blueprint to blend between the driven finger poses and the pose built from tracked joints. Called by the hand motion controller when hand tracking starts or stops being available.
fnHand_SetHandPoseHand Anim BP(HandPose: AnimSequenceBase)Implemented by the hand's animation blueprint to play a custom pose over the whole hand. Called by the hand motion controller, typically when something gripped supplies its own pose; an empty sequence means return to the driven poses.
fnHand_HandTrackingTransformsHand Anim BP(const Transforms: Transform[])Implemented by the hand's animation blueprint to receive the tracked joint transforms for this hand, relative to the hand mesh. Called by the hand motion controller once per frame while tracking is valid.
BPI_Pawn_VR1 members
extends Interface
KindNameSignatureDescription
fnInterface_RegisterControllerToVRPawnVR Pawn(MotionController: BP_MotionController, Side: E_Side = "Left")Implemented by the VR pawn to take ownership of a freshly spawned motion controller for one hand. The controller calls it on itself so the pawn can look it up later by side, for example when applying an ability restriction to both hands.

Libraries

ML_MotionController0 members
extends BP_MotionController

No editor-visible members; this asset configures defaults only.

Widgets/Crosshair

Widget_Crosshair2 members
extends UserWidget
KindNameSignatureDescription
fnShouldCrosshairBeVisible() → boolReturns true only while there is a local player controller, the mouse cursor is hidden and the pawn reports Game Only screen control. Any free-mouse or menu mode therefore hides the crosshair.
fnGet_Crosshair_ColorAndOpacity_0() → LinearColorReturns the tint for the crosshair image, taken from the interaction state the pawn is currently in, which is how the crosshair changes as you look at something you can act on. Falls back to opaque white when the pawn has no interaction state component.

Widgets/Touch

UI_Thumbstick6 members
extends UserWidget
KindNameSignatureDescription
varPositionVector2DCentre of the stick in viewport pixels, used as the reference point when deciding whether a touch has landed on it. Recalculated from the widget's own geometry every tick, so a value set in the designer is overwritten on the first frame.
varThumbstick SizeVector2DWidth and height of the stick in pixels, applied to the size box on construction. The larger of the two also serves as the capture radius, and half of each bounds how far the thumb image can be dragged from the centre.
varInvert XboolWhether the horizontal axis is flipped before the stick value is broadcast through Stick Input. The thumb image itself always follows the finger.
varInvert YboolWhether the vertical axis is flipped before the stick value is broadcast through Stick Input. Screen coordinates grow downwards, so a movement stick usually wants this on.
varScale OutputfloatMultiplier applied to the stick value before it is broadcast through Stick Input. Lower it for a look stick that should be less twitchy than the movement stick; 1 passes the full deflection through.
fnTouch Input Check(FingerIndex: ETouchIndex = "Touch1")Claims a finger for this stick if it is currently pressed and landed within the stick's radius, recording where it went down as the anchor for the deflection. Called from the tick for the first two fingers in turn while the stick is idle.
UI_TouchSimple4 members
extends UserWidget
KindNameSignatureDescription
eventOnPressed()Called when the on-screen jump button is pressed. Empty in this sample layout; fill it in, or copy the widget, to drive your own action.
eventStick Input(NewParam: Vector2D)Called every frame the left movement stick is being dragged, with its current deflection. Empty in this sample layout; feed the value into your pawn's movement input.
eventStick Input(NewParam: Vector2D)Called every frame the right aiming stick is being dragged, with its current deflection, already scaled down by that stick's output scale. Empty in this sample layout; feed the value into your pawn's look input.
eventOnReleased()Called when the on-screen jump button is released. Empty in this sample layout; pair it with On Pressed for actions that need a hold.