Both GetHandPositionAndOrientation(…) and GetTrackedDevicePositionAndOrientation(…) work in 4.18 and 4.19, but they’re for SteamVR only. And they’re for local player of course, so you need to replicate data manually.
//build.cs
PublicDependencyModuleNames.AddRange(
new string]
{
//...,
"SteamVR",
"HeadMountedDisplay",
"SteamVRController"
}
);
// header
// local values
UPROPERTY()
FVector LocRight, LocLeft;
UPROPERTY()
FRotator RotRight, RotLeft;
// relicated values
UPROPERTY(Replicated)
FVector LocRight_Replicated, LocLeft_Replicated;
UPROPERTY(Replicated)
FRotator RotRight_Replicated, RotLeft_Replicated;
// replication event
UFUNCTION(Server, Unreliable, WithValidation)
void Server_UpdateControllers(FVector LocR, FRotator RotR, FVector LocL, FRotator RotL);
bool Server_UpdateControllers_Validate(FVector LocR, FRotator RotR, FVector LocL, FRotator RotL) { return true; };
void Server_UpdateControllers_Implementation(FVector LocR, FRotator RotR, FVector LocL, FRotator RotL)
{
LocRight_Replicated = LocR; RotRight_Replicated = RotR;
LocLeft_Replicated = LocL; RotLeft_Replicated = RotL;
}
// .cpp
#include "SteamVRFunctionLibrary.h"
// in tick
const float InterpSpeed = 18.f;
if (IsLocallyControlled())
{
USteamVRFunctionLibrary::GetHandPositionAndOrientation(0, EControllerHand::Right, LocRight, RotRight);
USteamVRFunctionLibrary::GetHandPositionAndOrientation(0, EControllerHand::Left, LocLeft, RotLeft);
// send to server
if (GetIsReplicated()) Server_UpdateControllers(LocRight, RotRight, LocLeft, RotLeft);
}
else
{
// interp from relicated variables
// right
LocRight = FMath::VInterpTo(LocRight, LocRight_Replicated, DeltaTime, InterpSpeed);
RotRight = FMath::RInterpTo(RotRight, RotRight_Replicated, DeltaTime, InterpSpeed);
// left
LocLeft = FMath::VInterpTo(LocLeft, LocLeft_Replicated, DeltaTime, InterpSpeed);
RotLeft = FMath::RInterpTo(RotLeft, RotLeft_Replicated, DeltaTime, InterpSpeed);
}