top of page

VR Hand Component

Player’s hands are fully physically based and like in player class there was a huge research on immersion, collision and interaction with objects.

Название класса:

Include:

Тип:

Строки кода:

UVR_HandComponent

#include "VR/VR_Components/VR_HandComponent.h"

Player

6209

Общая информация

Description

VR Hand Component represents the player's hand in a VR environment. It utilizes physics for realistic interactions and employs physics constraints to achieve accurate physics-based behavior. The class is derived from UVR_MotionControllerComponent.

VR Hand is a hand which is being used by player. Hand is using physics and all interactions are using physics as well. The class uses Physics Constraint Component to achieve physics interactions.
VR Hands Demo Example

Main Features

  • Physics Interactions

  • Finger Collision

  • Weapon Interactions

  • Equipment Interactions

  • Finger IK (Inverse Kinematics)

  • Hand Animations

  • Menu Functionality

  • Radial Inventory Support

  • Pull Grab Functionality (Gravity Pull and Direct Pull)


Getting Started Guide

Creating the VR Hand Component Blueprint 🎨

You have two options to set up the VR Hand Component:

Option 1: Create a New Blueprint

  • Create Blueprint: Create a new Blueprint derived from UVR_HandComponent.

  • Setup: Configure the component from scratch according to your project's needs.

Option 2: Use the Existing Blueprint

  • Use Existing: Utilize the preconfigured Blueprint provided in the Demo Content folder.

  • Benefit: This Blueprint is already set up for easy integration and can be customized further.



Adding the VR Hand Component to Your Actor

  • Add Component: In your VR Player class/BP , select the UVR_HandComponent class/BP.

Customization and Setup

Visual Customization 🎨

Customize the appearance of the VR hand and related elements under the Visualization category:

  • Hand Mesh: Assign a skeletal mesh for the hand (e.g., SK_VR_Robot_Hand or your custom hand model).

  • Hand Collision Mesh: Set up a collision mesh for precise interactions.

  • Teleport Cylinder Mesh: Customize the visual indicator for teleportation destinations.

  • Teleport Arrow Mesh: Change the appearance of the teleport direction arrow.

  • Menu Cursor Mesh: Customize the cursor used during menu interactions.

  • Room Scale Mesh: Adjust the visualization of room-scale boundaries.

Animation and Finger IK Setup 🎬

Achieve realistic hand and finger movements by setting up animations and IK:

Step 1: Select Animation Blueprints

  • Assign Blueprints: Assign animation Blueprints to RealHandMesh and FakeHandMesh.

  • Requirement: These Blueprints should be derived from UVR_HandAnimationInstance.

    VR Hand Animation Animation Settings | Unreal Engine 5 | UE5
    VR Hand Component - Animation Settings
VR Hand Animation Blueprints | Unreal Engine 5 | UE5
VR Hand Animation Blueprints

Step 2: Choose Open and Closed Hand Animations

  • Open Hand Animation: Assign an animation for the open hand pose (a stretched hand works best).

  • Closed Hand Animation: Assign an animation for the closed fist pose.

  • Purpose: These animations are essential for natural grabbing and releasing actions.

Step 3: Set Tip Sockets for Each Finger

  • Assign Sockets: Under Tip Sockets, assign the socket names for each fingertip based on your hand skeleton.

  • Precision: This enables precise finger movement and collision detection.

    VR Hand Animation Blueprints | Unreal Engine 5 | UE5
    VR Hand Animation Blueprints

Step 4: Adjust Finger IK Settings

  • NumSamplePoints: Specify the number of segments or traces for each finger to control bending smoothness.

  • IkTraceCapsuleRadius: Set the trace capsule radius for IK calculations.

Step 5: Run Finger IK Setup

  • Automate IK: Use the RunFingerIKSetUp button or change any setting to automate the finger IK setup process.

Finger Collision Setup 🛡️

Enhance interaction accuracy with proper finger collision setup:

Step 1: Specify Hand Collision Mesh

  • Set Collision Mesh: Assign the collision mesh for the hand to enable precise environmental interactions.

    VR Hand Component Collision | UE5 | Unreal Engine 5
    VR Hand Component Collision

Step 2: Place Tip/Start Sockets

  • Position Sockets: Place the FingerStart and FingerTip scene components at the base and tip of each finger on the hand skeleton.

  • Components:

    • ThumbFingerStart and ThumbFingerTip

    • IndexFingerStart and IndexFingerTip

    • MiddleFingerStart and MiddleFingerTip

    • RingFingerStart and RingFingerTip

    • PinkyFingerStart and PinkyFingerTip

      VR Hand Skeleton Sockets | Unreal Engine 5 | UE5
      VR Hand Skeleton Sockets


Hand Physics and Constraints Configuration ⚙️

Configure physics settings to simulate realistic hand behavior:

Physics Constraints Overview

  • HandPhysicsConstraintInstance: Active when the hand is colliding; connects FakeHandMesh and PhysicsHandSocket.

  • HandPhysicsConstraintPDInstance: Active when the hand is not colliding; provides smoother movement.

  • PickPhysicsConstraintInstance: Manages object grabbing mechanics.

Constraint Parameters

VR Hand Component Physics Constraint Parametrs | UE5 | Unreal Engine 5
VR Hand Component Physics Constraint Parametrs
  • LinearForceLimit and AngularForceLimit: Control the maximum forces applied to the hand.

  • LinearPositionStrength and AngularPositionStrength: Adjust the strength of position constraints.

  • LinearVelocityStrength and AngularVelocityStrength: Control the responsiveness of hand movements.

  • Interpolation Speeds:

    • LinearPositionInterpSpeed

    • LinearVelocityInterpSpeed

Drag Curve

  • Assign DragCurve: In the Physics settings, assign a DragCurve to manage constraint behavior based on the distance between the hand and controller.

  • Note: A curve is necessary.

    The most important setting is a Drag Curve which effects on constraints depending on the hand and controller distance.
    Drag Curve

Pull Grab Functionality 🧲

Enable the ability to pull distant objects toward the hand:

Step 1: Enable Pull Grab

  • Activate: Set bCanPullGrab to true to enable pull grabbing.

Step 2: Select Pull Grab Type

  • Options:

    • Gravity Pull: Objects are smoothly pulled toward the hand (similar to Half-Life: Alyx).

    • Direct Pull: Objects move directly to the hand's location (similar to Boneworks).

Step 3: Configure Pull Parameters

  • PullGrabDistance: Maximum distance to initiate a pull grab.

  • PullCheckDelay: Interval between pull grab checks.

  • DirectPullGrabDistance: Specific distance setting for direct pulls.

  • DirectPullCurve: Assign a curve for smoothing direct pulls.

Inventory and Menu Setup 📋

Integrate menu systems and radial inventory support:

Menu Settings

  • Enable Menu: Set bTurnOnSpawnableHandMenu to true to activate menu functionality.

  • Assign Classes:

    • MainMenuClass: Assign the class to use for the main menu.

    • PauseMenuClass: Assign the class to use for the pause menu.

  • MenuLoadingWidgetClass: Assign a widget class for the loading indicator when accessing menus.

  • MenuGrabAnimation: Optionally specify an animation for menu interactions.

Radial Inventory

  • CA_Inventory Component: Use the CA_Inventory (UChildActorComponent) to manage the hand's radial inventory.

  • Activation: Press the thumbstick button on the right controller to access the radial inventory.

  • Setup: Assign the appropriate class to CA_Inventory and configure inventory items as needed.

Component Hierarchy and Descriptions

Hierarchical Structure

  • RootScene (USceneComponent)

    • The root component of the hand, serving as the base for all other components.

  • Hands (USceneComponent)

    • Contains all hand-related components.

    • HandSocket (USphereComponent)

      • Serves as a socket for the non-physical hand mesh.

      • FakeHandMesh (USkeletalMeshComponent)

        • A non-physical skeletal mesh representing the hand when not interacting with physics objects.

        • ArcNiagara (UNiagaraComponent)

          • Used for teleportation arcs.

        • WidgetInteractionComponent (UWidgetInteractionComponent)

          • Facilitates interaction with UI widgets.

    • PhysicsHandSocket (USphereComponent)

      • Serves as a socket for the physical hand mesh and simulates physics.

      • RealHandMesh (USkeletalMeshComponent)

        • The physical hand mesh that interacts with physics objects.

        • Finger Collisions (UCapsuleComponent)

          • ThumbFingerCollision

          • IndexFingerCollision

          • MiddleFingerCollision

          • RingFingerCollision

          • PinkyFingerCollision

        • Finger Scene Components (USceneComponent)

          • Start and tip components for each finger (e.g., ThumbFingerStart, ThumbFingerTip).

        • GrabRoot (USceneComponent)

          • Base component for grabbing functionality.

          • GrabDirection (UArrowComponent)

          • Indicates the direction for grabbing actions.

        • CA_Inventory (UChildActorComponent)

          • Manages the hand's radial inventory.

        • MenuWristLoader (UWidgetComponent)

          • Displays the menu loading bar.

        • RealHandCollision (UStaticMeshComponent)

          • Provides collision for the physical hand mesh.

  • ArcDirection (UArrowComponent)

    • Determines the direction of the teleportation arc.

  • PullDirection (UArrowComponent)

    • Indicates the direction for pull grabbing.

  • ArcEndPoint (UStaticMeshComponent)

    • Represents the end point of the teleportation arc.

  • MenuCursor (UStaticMeshComponent)

    • Displays the cursor during menu interactions.

  • TeleportCylinder (UStaticMeshComponent)

    • Visualizes the teleportation destination area.

    • Arrow (UStaticMeshComponent)

      • Shows the teleportation direction.

      • RoomScaleMeshComponent (UStaticMeshComponent)

        • Outlines the room-scale boundaries.

  • WidgetSphereMesh (UStaticMeshComponent)

    • Used for widget interactions.

  • PullVisualizer (USceneComponent)

    • Visualizes the pull grab effect.

  • DirectPullTimeLine (UTimelineComponent)

    • Manages the timing for direct pull animations.

Tick Algorithm Overview

The VR Hand Component performs various functions each frame to ensure smooth interactions:

  • HandPhysicsTick

    • Manages physics constraints based on collision status.

    • Switches between HandPhysicsConstraintInstance and HandPhysicsConstraintPDInstance.

  • CheckAimToGrab

    • Moves the hand closer to nearby grabbable objects using physics constraints.

  • UpdateHandAnimation

    • Updates hand animations based on input and interactions.

    • Adjusts finger poses using IK.

  • UpdateRoomScaleOutline

    • Adjusts the room-scale boundary visualization relative to the teleport destination.

  • CheckMenuStatus

    • Manages menu activation and adjusts hand visibility and functionality accordingly.

  • UpdateWidgetCursor

    • Moves the cursor on UI widgets during interactions.

  • CheckHandsAndControllerDist

    • Ensures the hand stays within a reasonable distance from the controller.

    • Adjusts physics constraints if necessary.

  • CheckControllerAndPickDist

    • Drops held objects if they are too far from the controller.

  • CheckGrabPossibility

    • Verifies if grabbing is possible based on object weight, distance, and player input.

  • CheckMenuButtonPress

    • Monitors the duration of menu button presses to trigger menu actions.

  • UpdateAllFingersCollision

    • Recalculates finger collisions based on the current hand pose.

  • MakeUpdateWidgetLookAtCamera

    • Keeps the menu or UI widget facing the player.

The VR Hand Component uses three physics constraints managed via FConstraintInstance:

  • HandPhysicsConstraintInstance: Connects the FakeHandMesh and PhysicsHandSocket when the hand is colliding.

  • HandPhysicsConstraintPDInstance: Used when the hand is not colliding.

  • PickPhysicsConstraintInstance: Manages object grabbing mechanics.

These constraints are dynamically switched in HandPhysicsTick based on the hand's collision status. All relevant components have "Simulation Generates Hit Events" enabled for proper functionality.


HandPhysicsConstraint is turned on when hand is colliding and HandPhysicsConstraintPD when hand is not colliding. This is woking by hit events so make sure that every finger collision, handcollision and other objects which developer attached has "Simulation Generate Hit Events" set to true.
Simulation Generate Hit Events

Hand Skeleton

  • Skeleton Compatibility: Supports both SteamVR and Unreal Engine XR skeletons.

  • Settings:

    • Reflect Left Hand: Mirrors the hand model for the left hand.

    • Using Steam VR Skeleton: Enables compatibility with SteamVR skeleton.

  • Finger Bones: Configurable bone names for each finger to ensure accurate finger collision and IK.


The default settings are using SteamVR skeleton but it is possible to use Unreal Engine XR skeleton. In the Setting there are Hand section in which you can find the following variables: Reflect Left Hand, Using Steam VR Skeleton and finger bones(This is used in finger collision).
Hand Skeleton Settings

Finger Collision(UE 4.27)

Finger collision are using physics blend(works with SteamVR skeleton only). Requires skeletal physics asset set up(See demo skeletal physics asset example).


Line traces for Grab IK(Technical info)

Hand uses line traces for each finger. Each finger rotation value is from 0 to 1 so the value of each line trace is 1/NumberOfTraces(4)=0.25 (Trace 1: 0-0.25, Trace 2: 0.25-0.5, Trace 3: 0.5-0.75 and Trace 3: 0.75-1).

Hand uses 4 line traces(Arrow Componets) for each finger. Each finger rotation value is from 0 to 1 so the value of each line trace is 1/NumberOfTraces(4)=0.25 (Trace 1: 0-0.25, Trace 2: 0.25-0.5, Trace 3: 0.5-0.75 and Trace 3: 0.75-1). The set up requires animation blueprint(For debugin positions) in which IK blend per bone is connected to the output(Picture below). Position of the arrows for the finger should match the finger position in the value range.
Animation Blueprint(For debugin positions)

Menu settings

Menu(Actor attached to the FakeHandMesh) can be spawned after holding A button on the left controller(Loading ring will apear while holding the button). Main Menu class and Pause Menu class is classes which will be spawned in certain conditions(Main Menu if Player has true at Menu Status and Pause Menu if player pressed the button). Menu grab animation can be specified.(Do not to forget to select the classes otherwise project will crash)


Hand radial inventory

CA_Inventory(Child Actor Component) is a inventory actor which can be spawned by pressing the thumbstick button on the rightcontroller(Class should be selected at least with 0 values to avoid issues. See VR Hand Inventory for more information).

Other Settings

Ammo Clips - This is an array of classes in which the information of ammo classes is stored. Index is a caliber type which is get from Player(See VR Player). This variable is used in the grabbing function. If hand is in the ammo box and player has some ammo it will spawn the actor of the class from that array by a caliber(Index).

Hit Surface Haptic Effect - This is a Haptic Effect which is playing when hand hit the surface.

Teleport - Variables which effect the teleport.

Grab - Variables which effect the teleport(Speed, Sound etc.).




Справочник API Blueprint

Public Member Functions


 

 


virtual void 

OnConstruction (const FTransform &Transform) override

 


virtual void 

BeginPlay () override

 


virtual void 

Tick (float DeltaTime) override

 


virtual void 

EndPlay (EEndPlayReason::Type EndPlayReason) override

 


void 

 


void 

 


void 

 


void 

 


bool 

 


void 

 

If grab button is pressed.

 


void 

 

Release attached Actor.

 


void 

 


void 

 


bool 

TraceTeleportDestination (TArray< FVector > &TracePoints, FVector &NavMeshLocation, FVector &TraceLocation, FRotator &TraceRotation)

 

Traces Teleport Destination , checks if teleport is possible.

 


void 

 

Clears Arc.

 


void 

UpdateArcSpline (bool FoundValidLocation, TArray< FVector > SplinePoints)

 

Updates Arc Spline.

 


void 

UpdateArcEndPoint (bool ValidLocationFound, FVector NewLocation)

 

Updates Arc End Point.

 


void 

GetTeleportDestination (FVector &MyLocation, FRotator &MyRotation)

 

Gets teleport Destination.

 


void 

 

Sets all Fingers IK.

 


void 

ShowTeleportDestenation (bool IsValidTeleportDestination, FVector TraceLocation, FRotator TraceRotation)

 


void 

SetSingleFingerIK (UArrowComponent FingerTrace1, UArrowComponent FingerTrace2, UArrowComponent FingerTrace3, UArrowComponent FingerTrace4, EFinger Finger)

 

Sets Ik for SingleFinger.

 


void 

LineTraceAlongArrow (class UArrowComponent *ArrowToTrace, bool &Hit, float &TraceLength, FHitResult &OutHits)

 

Trace line allong the arrow component.

 


float 

CalculateRatio (float TraceLength, int ArrowNumber)

 

Calculates Rotation.

 


void 

CalculateIKLocations (FVector WorldImpact, FVector &EffectorLocation)

 


void 

ApplyIKToABP (FVector EffectorLocation, float Ratio, EFinger Finger, bool hit)

 

Apply Rotation to Animation blueprint.

 


void 

 

Setup Room Scale Outline.

 


void 

 

Update Room Scale Outline.

 


void 

RumbleController (float Intensity, UHapticFeedbackEffect_Base *HapticEffect)

 

Vibrate the Controller using the Habtics.

 


void 

OnComponentBeginOverlap (class UPrimitiveComponent OverlappedComp, AActor OtherActor, class UPrimitiveComponent *OtherComp, int32 OtherBodyIndex, bool bFromSweep, const FHitResult &SweepResult)

 

For Rumble Controller when overlapping valid StaticMesh.

 


void 

 


void 

SetTeleportRotation (FRotator &NewTeleportRotation)

 

Set Teleport Rotation , used in Player_Pawn.

 


void 

 

Checks distance between Controller and Picked object .

 


void 

 

Checks distance between Hands and Controller.

 


void 

 


bool 

TryAimToGrab (FHitResult &Hit, bool ForceInteraction)

 


void 

 

Checks if Teleport is active. Updates Arc Spline , using UpdateArcSpline(bIsValidTeleportDestination, TracePoints) ; Updates Arc end point , using UpdateArcEndPoint(bIsValidTeleportDestination, TraceLocation).

 


virtual void 

 

Trigger Pressed.

 


virtual void 

 

Trigger Touch.

 


virtual void 

 

Grip Pressed.

 


virtual void 

 

Thumb Pressed.

 


virtual void 

 

Trigger Released.

 


virtual void 

 

Trigger UnTouch.

 


virtual void 

 

Grip Released.

 


virtual void 

 

Thumb Released.

 


virtual void 

 

A Pressed.

 


virtual void 

 

A Released.

 


virtual void 

 

B Pressed.

 


virtual void 

 

B Released.

 


virtual void 

 

Sets true if Trackpad being Touched.

 


virtual void 

 


virtual void 

SetIndexPushInst (float inst)

 


virtual void 

SetGripPushInst (float inst)

 


virtual void 

SetTrackpad_Y (float inst)

 


virtual void 

SetAllowAmmo (bool Allow)

 


virtual void 

HandsPickObjHandle (bool Attach)

 


AActor * 

 


void 

SetDontLostConnection (bool DontAllow)

 


void 

SetMainMenuStatus (bool MainMenuStatus)

 

Turns on\off widget component.

 


void 

SetOwnerPawn (AActor *ActorToSet)

 

Sets owner of the MotionController(Player)

 


void 

 


void 

UpdateFingerCollision (UCapsuleComponent Collision, USceneComponent Start, USceneComponent *Tip)

 


void 

 


void 

EnableFingerCollision (bool Enable)

 


bool 

 


void 

 


void 

 


void 

SetCurrentWidgetHand (bool ThisHand)

 

Sets widget on current hand.

 


void 

 

Updates Widget Cursor.

 


void 

 

Check if the grab is possible.

 


void 

CheckPhysBlend (bool force=false)

 


void 

UpdatePhysBlendForFinger (EFinger Finger, FFingerCurls CurrentFingerCurls, bool force=false)

 


void 

SetLessPhysHands (bool newstatus)

 

Sets bLessPhysHands.

 


void 

 


void 

 


void 

 


void 

 


bool 

DoTryGrabbing (FHitResult &Hit, bool ForceInteraction)

 


bool 

TryGrabbing (FHitResult &Hit, bool ForceInteraction)

 


void 

CheckFingerCollisionOverlap (TArray< FName > &FingerSocketsNames, TArray< FName > &FingerBonesNames)

 


void 

UpdateGrabAnimation (UAnimSequence *NewAnimation)

 


void 

UpdateTriggerPressedAnimation (UAnimSequence *NewAnimation)

 


void 

UpdateAPressedAnimation (UAnimSequence *NewAnimation)

 


FORCEINLINE bool 

GetIsGrabbed () const

 


FORCEINLINE bool 

GetHasWeapon () const

 


FORCEINLINE uint8 

GetCaliber () const

 


FORCEINLINE USkeletalMeshComponent * 

GetHandMesh () const

 


FORCEINLINE USkeletalMeshComponent * 

 


FORCEINLINE FVector 

 


FORCEINLINE FVector 

 


FORCEINLINE EControllerHand 

GetHand () const

 


FORCEINLINE UPhysicsConstraintComponent * 

 


FORCEINLINE USceneComponent * 

 


FORCEINLINE AActor * 

 


FORCEINLINE AActor * 

 


FORCEINLINE AActor * 

GetOwnerPawn () const

 


FORCEINLINE bool 

GetAllowAmmo () const

 


FORCEINLINE AVR_HandInventory

GetInventory () const

 


FORCEINLINE bool 

IsClimbing () const

 


FORCEINLINE USphereComponent * 

 


FORCEINLINE UStaticMeshComponent * 

 


void 

EnableLoadingRoom (bool Enable)

 


void 

SetHandIsColliding (bool IsColliding)

 


FORCEINLINE bool 

IsHandClosed () const

 


FORCEINLINE bool 

 


FORCEINLINE FVector 

 


FORCEINLINE FFingerCurls 

 


void 

OnHit (AActor SelfActor, AActor OtherActor, FVector NormalImpulse, const FHitResult &Hit)

 


void 

SetInventoryAccess (bool Access)

 


void 

 


FORCEINLINE FRotator 

 


FORCEINLINE bool 

 


FORCEINLINE bool 

 


FORCEINLINE bool 

 


Public Attributes


bool 

 


bool 

 


bool 

 


bool 

 


bool 

bHitHand = false

 


bool 

 


bool 

 


bool 

 


bool 

 


float 

 


float 

 


float 

 


float 

 


FVector 

 


EControllerHand 

 


Protected Member Functions


void 

 


void 

 


USceneComponent * 

GetNearestGrabComponent (AActor *Actor, FVector TestLocation, bool ForceCheckPriority)

 



bottom of page