Home › System plugins › AFS_UI_Hand
System

AFS_UI_Hand

Wrist-mounted UI that appears when the palm turns toward the face, within a configurable angle.

What it gives you

  • A watch-style panel anchored to the hand
  • Automatic show and hide from palm orientation
  • No input needed to summon it

Requires

None

Required by

None

3 assets18 API members

Description

Hand UI solves the problem of where to put persistent information in VR. Anchored to the world it gets lost; anchored to the head it is intrusive. Anchored to the wrist it behaves like a watch — you look at it when you want it and forget it otherwise.

BPC_ControllerAbility_HandUI spawns a helper actor holding your widget and shows it when the angle between the palm normal and the direction to the head falls within Appear Angle. There is no input to press and nothing to toggle.

Setup

  1. Enable AFS_UI_Hand.
  2. Add BPC_ControllerAbility_HandUI to the motion controller that should carry the panel.
  3. Set Widget VR to a widget deriving from WBP_Base.
  4. Tune Appear Angle — 40° is the default and works well for most users.
The wrist panel open on an upturned palm
AFS_UI_Hand_result.pngThe wrist panel open on an upturned palm
The wrist panel open on an upturned palm

Usage

Choosing content

Keep it glanceable. Status, a clock, a small set of toggles. Anything needing sustained attention belongs in pawn UI or the menu.

Which hand

Add the component to one controller only. Most users prefer the non-dominant hand, mirroring a watch.

Key properties

PropertyWhen to change
Appear AngleWiden if the panel is hard to summon, narrow if it appears unintentionally
Widget VRThe widget class shown on the wrist

Extending

Derive from BP_Helper_HandUI to change how the panel is positioned or animated.

Example map

Map_Examples_HandUI demonstrates the wrist panel.

Troubleshooting

The panel never appears. The component is on a controller whose palm normal is not oriented as expected — check the hand mesh's forward axis, or widen Appear Angle to confirm.

API reference

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

Components

BPC_ControllerAbility_HandUI5 members
extends BPC_ControllerAbility

Hand ability that carries a UMG menu on the palm. While active it spawns the hand UI helper, for the locally controlled pawn only, and the helper shows or hides the menu as the palm turns towards the head past Appear Angle. Add it to a motion controller and set Widget VR to the widget class the hand should carry.

KindNameSignatureDescription
varAppear AngleConfigfloatAngle threshold, in degrees, handed to the hand panel as its Hand Angle when the helper is spawned. The comparison carries a fifty per cent deadzone, so at the default of 40 the panel opens once the measured angle drops below 20 degrees and closes again above 60. Read once as the ability activates; changing it afterwards does nothing to a panel already spawned.
varWidget VRContentclass<WBP_Base>Widget class shown on the hand, passed to the helper actor as its widget class at the moment the ability activates. Leave it empty and the panel still spawns with nothing drawn in it. Only read on activation, so swapping it at runtime takes effect after the ability has been deactivated and reactivated.
varReferencesReferencesStruct_ReferencesDynamic references carried through to the widget when the panel is built, each entry resolved into an actor by class, or by class and tag, and stored under its key for the widget to look up by name. Leave empty for widgets that need no context.
eventSetHandUI(set: bool)Creates or removes the hand UI helper. True spawns one, but only when there is not one already, handing it the VR widget, the dynamic references, the appear angle, whether the ability is active and which side it belongs to, and attaches it to this component. False destroys the helper for the locally controlled pawn and forgets it. Whether the menu is actually on screen is the helper's palm-angle check, not this.
eventInitiateControllerAbility(Pawn: Pawn, MotionController: Actor, Side: E_Side)Override of the ability's start-up hook. It lets the parent do its work and then calls Set Hand UI with true, which is what puts the palm menu into the world as soon as the ability is initiated.

Helper

BP_Helper_HandUI9 members
extends BP_Helper_ControllerAbility

World-side actor for the hand UI ability: a spring arm that lets the menu lag behind the hand, an anchor the menu element attaches to, and a ticked check of the palm angle that plays the menu in or out. Spawned by the ability rather than placed, and the element carrying the actual widget connects to its anchor.

KindNameSignatureDescription
varIs VisibleStateboolWhether the panel is currently open. Defaults to true, but the hand UI ability spawns the helper with it false and Show Hand UI owns it from then on; writing to it directly moves nothing on screen, because it is the scale curve started by Show Hand UI that opens and closes the panel.
varHand UIComponentComponentsBPC_ControllerAbility_HandUIObject the panel was raised on behalf of, filled in on spawn with the hand UI ability that created this helper. Nothing in the helper itself reads it; it is held as the trail back to the owner for the element and the widget it hosts.
varWidget ClassContentclass<WBP_Base>Class of widget the panel is meant to show, handed down from the ability's VR widget as the helper is spawned. The helper creates no widget of its own; the element snapped onto its anchor is what builds one, so this is carried rather than used here.
varReferencesContentStruct_ReferencesDynamic references travelling alongside the widget class, resolved into actors at the moment the widget is finally created and stored under their keys for it to read. Leave empty for widgets that need no context.
varHand AngleSettingsfloatAngle threshold, in degrees, that the tick check compares the hand's current angle against to decide whether the panel should be open, overwritten on spawn with the ability's Appear Angle. The deadzone is half the threshold, so at the default of 30 the panel opens below 15 degrees and closes above 45, which stops it flickering at the boundary. Checked ten times a second after physics.
varActiveStateboolWhether the ability wants the palm menu at all. Written through Set Active and checked by the palm-angle test alongside whether the hand is in view: the menu opens only when both are true, so this is the flag that silences the menu without destroying the helper.
fnCheckToShowHandUI()Decides whether the panel should be open. It opens only while the hand is in view and Active is set, and closes in every other case. Reached from the tick and from Set Active, so it is the single place that decision is made.
eventShowHandUI(Set: bool)Opens or closes the panel by playing the 0.3 second scale curve forwards, growing the handle from a tenth of its size and sliding it 5 centimetres into place, or reversing it to fold it away. Repeated calls with the value it already holds are swallowed. Called from tick as the hand crosses the hand angle; the curve's visibility key is what shows or hides the attached element.
eventSetActive(Active: bool)Switches whether the ability wants the menu and immediately re-runs the open and closed check, so the panel plays in or out as soon as the flag changes rather than at the next tick.
BP_Helper_HandUI_Element4 members
extends Actor

Actor carrying the palm menu itself: a widget component at hand scale, a pickup grip and a connector holding it on the hand UI helper's anchor. Because it is a separate actor with a grip of its own, the menu can be pulled off the hand and left hanging in the world. Spawned for you; the widget class comes from the hand UI ability.

KindNameSignatureDescription
varWidget ClassContentclass<WBP_Base>Class of widget created on the element's widget component at begin play, along with the reference struct. Leave it empty and the element still spawns and snaps to the hand, but the panel stays blank. Read once, so assigning it later has no effect.
varReferencesContentStruct_ReferencesDynamic references resolved into the widget at the moment its class is created on begin play, each entry found by class, or by class and tag, and stored under its key for the widget to read. Leave empty for widgets that need no context.
varHelper Hand UIStateBP_Helper_HandUIThe hand panel helper this element belongs to. Its anchor is what the element's connector attaches itself to on begin play, so leaving this empty strands the element wherever it was spawned instead of seating it on the hand.
fnSetElementVisibility(Show: bool)Shows or hides the hosted widget, fading it over 0.4 seconds with the hand UI open or close cue, and registers or unregisters the stand-in that other clients see through the local player pawn's replicated UI component. Called by the hand panel helper as the hand is raised and lowered, and when an element snaps onto a hand that is already lowered.