4#include "Net/UnrealNetwork.h"
8 : Super(ObjectInitializer)
10 this->SetGenerateOverlapEvents(
true);
11 this->PrimaryComponentTick.bStartWithTickEnabled =
false;
12 PrimaryComponentTick.bCanEverTick =
true;
24#if PHYSICS_INTERFACE_PHYSX
75 this->SetCollisionResponseToAllChannels(ECollisionResponse::ECR_Overlap);
84void UVRLeverComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps)
const
86 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
98 Super::PreReplication(ChangedPropertyTracker);
128 Super::TickComponent(DeltaTime, TickType, ThisTickFunction);
164 FQuat LerpedQuat = FMath::QInterpConstantTo(CurRelativeTransform.GetRelativeTransform(
InitialRelativeTransform).GetRotation(), FQuat::Identity, DeltaTime, FMath::DegreesToRadians(
LeverReturnSpeed));
166 if (LerpedQuat.IsIdentity())
168 this->SetComponentTickEnabled(
false);
241 Super::OnUnregister();
251 uint8 GripID = GripInformation.
GripID;
282 FVector CurInteractorLocation = (
InteractorOffsetTransform * PivotTransform).GetRelativeTransform(CurrentRelativeTransform).GetTranslation();
297 bool bWasClamped = nAngle > MaxAngle;
298 nAngle = FMath::Clamp(nAngle, 0.0f, MaxAngle);
299 Rot = FQuat(nAxis, nAngle).Rotator();
312 FTransform NewPivTrans = PivotTransform.GetRelativeTransform((CalcTransform * ParentTransform));
313 CurInteractorLocation = NewPivTrans.GetTranslation();
315 FVector OffsetVal = CurInteractorLocation + NewPivTrans.GetRotation().RotateVector(
InteractorOffsetTransform.GetTranslation());
318 CurInteractorLocation -= OffsetVal;
322 CurInteractorLocation = (CalcTransform * ParentTransform).InverseTransformPosition(GrippingController->
GetPivotLocation());
332 FQuat newLocalRot = CalcTransform.GetRotation() * FQuat(FVector::UpVector, FMath::DegreesToRadians(CurrentLeverYawAngle));
333 this->SetRelativeRotation(newLocalRot.Rotator());
348 this->SetRelativeRotation(CalcTransform.Rotator());
377 FTransform ReversedRelativeTransform = FTransform(GripInformation.
RelativeTransform.ToInverseMatrixWithScale());
378 FTransform CurrentTransform = this->GetComponentTransform();
379 FTransform RelativeToGripTransform = FTransform::Identity;
384 FVector InitialInteractorOffset = ReversedRelativeTransform.GetTranslation();
385 FTransform InitTrans = ReversedRelativeTransform;
386 InitialInteractorOffset.X = 0;
387 InitialInteractorOffset.Y = 0;
392 InitialInteractorOffset = ReversedRelativeTransform.GetTranslation();
393 InitialInteractorOffset.Z = 0;
395 InitTrans.AddToTranslation(-InitialInteractorOffset);
396 RelativeToGripTransform = InitTrans * CurrentTransform;
400 RelativeToGripTransform = ReversedRelativeTransform * CurrentTransform;
411 qRotAtGrab = this->GetComponentTransform().GetRelativeTransform(CurrentRelativeTransform).GetRotation();
415 qRotAtGrab = this->GetComponentTransform().GetRelativeTransform(CurrentRelativeTransform).GetRotation();
443 this->SetComponentTickEnabled(
true);
453 FAttachmentTransformRules AttachRules(EAttachmentRule::KeepWorld,
true);
460 this->SetComponentTickEnabled(
true);
466 this->SetComponentTickEnabled(
false);
586 if (OverridePrefix.IsNone())
587 bSecondarySlot ? OverridePrefix =
"VRGripS" : OverridePrefix =
"VRGripP";
599 CurHoldingControllers.Empty();
659#if PHYSICS_INTERFACE_PHYSX
663 PxScene* PScene = HandleData->getScene();
669 HandleData->release();
670 PScene->unlockWrite();
687#if PHYSICS_INTERFACE_PHYSX
693 FBodyInstance* rBodyInstance = this->GetBodyInstance(NAME_None);
700 FTransform A2Transform = FTransform::Identity;
703 UPrimitiveComponent * PrimComp = Cast<UPrimitiveComponent>(
ParentComponent.Get());
706 A2Transform = PrimComp->GetComponentTransform();
711 FTransform RefFrame2 = FTransform(
InitialRelativeTransform.GetRotation() * AngularRotationOffset.Quaternion(), A2Transform.InverseTransformPosition(GetComponentLocation()));
716 FPhysicsCommand::ExecuteWrite(BodyInstance.ActorHandle, [&](
const FPhysicsActorHandle&
Actor)
719 if (PxRigidActor* PActor = FPhysicsInterface::GetPxRigidActor_AssumesLocked(Actor))
721 PxScene* Scene = PActor->getScene();
722 PxD6Joint* NewJoint = NULL;
723 PxRigidDynamic * ParentBody = NULL;
725 if (ParentComponent.IsValid())
727 UPrimitiveComponent * PrimComp = Cast<UPrimitiveComponent>(ParentComponent.Get());
729 if (PrimComp && PrimComp->BodyInstance.IsValidBodyInstance())
731 ParentBody = FPhysicsInterface::GetPxRigidDynamic_AssumesLocked(PrimComp->BodyInstance.ActorHandle);
736 NewJoint = PxD6JointCreate(Scene->getPhysics(), ParentBody, U2PTransform(RefFrame2), PActor, PxTransform(PxIdentity));
745 NewJoint->userData = NULL;
746 HandleData = NewJoint;
749 FPhysScene* RBScene = FPhysxUserData::Get<FPhysScene>(Scene->userData);
754 NewJoint->setBreakForce(PX_MAX_REAL, PX_MAX_REAL);
759 PxConstraintFlags Flags = NewJoint->getConstraintFlags();
763 Flags |= PxConstraintFlag::eCOLLISION_ENABLED;
766 Flags &= ~PxConstraintFlag::ePROJECTION;
768 NewJoint->setConstraintFlag(PxConstraintFlag::ePROJECTION, true);
769 NewJoint->setProjectionAngularTolerance(FMath::DegreesToRadians(0.1f));
770 NewJoint->setProjectionLinearTolerance(0.1f);
771 NewJoint->setConstraintFlags(Flags);
774 NewJoint->setMotion(PxD6Axis::eX, PxD6Motion::eLOCKED);
775 NewJoint->setMotion(PxD6Axis::eY, PxD6Motion::eLOCKED);
776 NewJoint->setMotion(PxD6Axis::eZ, PxD6Motion::eLOCKED);
778 NewJoint->setMotion(PxD6Axis::eTWIST, LeverRotationAxis == EVRInteractibleLeverAxis::Axis_X || LeverRotationAxis == EVRInteractibleLeverAxis::Axis_XY ? PxD6Motion::eLIMITED : PxD6Motion::eLOCKED);
779 NewJoint->setMotion(PxD6Axis::eSWING1, LeverRotationAxis == EVRInteractibleLeverAxis::Axis_Y || LeverRotationAxis == EVRInteractibleLeverAxis::Axis_XY ? PxD6Motion::eLIMITED : PxD6Motion::eLOCKED);
780 NewJoint->setMotion(PxD6Axis::eSWING2, PxD6Motion::eLOCKED);
782 const float CorrectedLeverLimit = (LeverLimitPositive + LeverLimitNegative) / 2;
783 const float LeverLimitRad = CorrectedLeverLimit * (PI / 180.0f);
787 PxReal ZLimitAngle = FMath::ClampAngle(CorrectedLeverLimit, KINDA_SMALL_NUMBER, 179.9999f) * (PI / 180.0f);
788 PxReal YLimitAngle = FMath::ClampAngle(CorrectedLeverLimit, KINDA_SMALL_NUMBER, 179.9999f) * (PI / 180.0f);
791 NewJoint->setSwingLimit(PxJointLimitCone(YLimitAngle, ZLimitAngle));
792 NewJoint->setTwistLimit(PxJointAngularLimitPair(-LeverLimitRad, LeverLimitRad));
818 NewAngle = -NewAngle;
820 FVector ForwardVector = DualAxisForwardVector;
824 ForwardVector = FVector(FMath::Sign(NewAngle), 0.0f, 0.0f);
break;
826 ForwardVector = FVector(0.0f, FMath::Sign(NewAngle), 0.0f);
break;
828 ForwardVector = FVector(0.0f, 0.0f, FMath::Sign(NewAngle));
break;
832 FQuat NewLeverRotation(ForwardVector, FMath::DegreesToRadians(FMath::Abs(NewAngle)));
855 FQuat CurrentRelRot = RelativeToSpace.GetRotation();
856 FVector UpVec = CurrentRelRot.GetUpVector();
861 FullCurrentAngle = FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(UpVec, FVector::UpVector)));
864 AllCurrentLeverAngles.Roll = FMath::Sign(UpVec.Y) * FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(FVector(0.0f, UpVec.Y, UpVec.Z), FVector::UpVector)));
865 AllCurrentLeverAngles.Pitch = FMath::Sign(UpVec.X) * FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(FVector(UpVec.X, 0.0f, UpVec.Z), FVector::UpVector)));
869 FVector ProjectedLoc = FVector(UpVec.X, UpVec.Y, 0.0f).GetSafeNormal();
870 AllCurrentLeverAngles.Pitch *= FMath::Clamp(1.0f - (FMath::Abs(FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(ProjectedLoc, FMath::Sign(UpVec.X) * FVector::ForwardVector)))) /
AngleThreshold), 0.0f, 1.0f);
871 AllCurrentLeverAngles.Roll *= FMath::Clamp(1.0f - (FMath::Abs(FMath::RadiansToDegrees(FMath::Acos(FVector::DotProduct(ProjectedLoc, FMath::Sign(UpVec.Y) * FVector::RightVector)))) /
AngleThreshold), 0.0f, 1.0f);
903 float TargetAngle = 0.0f;
910 if (CurrentAngle >= 0)
927 this->SetComponentTickEnabled(
false);
951 float LerpedVal = FMath::FInterpConstantTo(CurrentAngle, TargetAngle, DeltaTime, FinalReturnSpeed);
953 if (FMath::IsNearlyEqual(LerpedVal, TargetAngle))
959 this->SetRelativeRotation(CalcTransform.Rotator());
963 this->SetComponentTickEnabled(
false);
967 this->SetRelativeRotation(CalcTransform.Rotator());
973 this->SetRelativeRotation(CalcTransform.Rotator());
979 float ReturnAxis = 0.0f;
EGripMovementReplicationSettings
UENUM(Blueprintable)
@ ForceClientSideMovement
@ ForceServerSideMovement
ESecondaryGripType
UENUM(Blueprintable)
EGripCollisionType
UENUM(Blueprintable)
EGripLateUpdateSettings
UENUM(Blueprintable)
EGripInterfaceTeleportBehavior
UENUM(Blueprintable)
EVRInteractibleAxis
UENUM(Blueprintable)
@ LerpToMaxIfOverThreshold
EVRInteractibleLeverAxis
UENUM(Blueprintable)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = MotionController)
bool HasGripAuthority(const FBPActorGripInformation &Grip)
FORCEINLINE FVector GetPivotLocation()
void GetGripByID(FBPActorGripInformation &Grip, uint8 IDToLookForGrip, EBPVRResultSwitch &Result)
UFUNCTION(BlueprintCallable, Category = "GripMotionController", meta = (ExpandEnumAsExecs = "Result")...
FVRGripControllerOnGripOutOfRange OnGripOutOfRange
UPROPERTY(BlueprintAssignable, Category = "GripMotionController")
bool DropObjectByInterface(UObject *ObjectToDrop=nullptr, uint8 GripIDToDrop=0, FVector OptionalAngularVelocity=FVector::ZeroVector, FVector OptionalLinearVelocity=FVector::ZeroVector)
UFUNCTION(BlueprintCallable, Category = "GripMotionController")
FORCEINLINE FTransform GetPivotTransform()
static void GetGripSlotInRangeByTypeName_Component(FName SlotType, USceneComponent *Component, FVector WorldLocation, float MaxRange, bool &bHadSlotInRange, FTransform &SlotWorldTransform, FName &SlotName, UGripMotionControllerComponent *QueryController=nullptr)
UFUNCTION(BlueprintPure, Category = "VRGrip", meta = (bIgnoreSelf = "true", DisplayName = "GetGripSlo...
static FRotator GetHMDPureYaw_I(FRotator HMDRotation)
static float GetDeltaAngleFromTransforms(EVRInteractibleAxis RotAxis, FTransform &InitialRelativeTransform, FTransform &CurrentRelativeTransform)
static FRotator SetAxisValueRot(EVRInteractibleAxis RotAxis, float SetValue)
static float GetAtan2Angle(EVRInteractibleAxis AxisToCalc, FVector CurInteractorLocation, float OptionalInitialRotation=0.0f)
static FVector SetAxisValueVec(EVRInteractibleAxis RotAxis, float SetValue)
static FTransform Interactible_GetCurrentParentTransform(USceneComponent *SceneComponentToCheck)
UFUNCTION(BlueprintPure, Category = "VRInteractibleFunctions", meta = (bIgnoreSelf = "true"))
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = (VRExpansionPlugin))
float MaxLeverMomentum
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings",...
float LeverLimitNegative
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent", meta = (ClampMin = "0....
FBPAdvGripSettings AdvancedGripSettings_Implementation() override
UVRLeverComponent(const FObjectInitializer &ObjectInitializer)
void OnGrip_Implementation(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation) override
void OnGripRelease_Implementation(UGripMotionControllerComponent *ReleasingController, const FBPActorGripInformation &GripInformation, bool bWasSocketed=false) override
FTransform InteractorOffsetTransform
void OnUsed_Implementation() override
float LeverRestitution
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings",...
EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override
void TickGrip_Implementation(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation, float DeltaTime) override
bool bReplicateMovement
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
FBPGripPair HoldingGrip
UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface")
FTransform_NetQuantize InitialRelativeTransform
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRLeverCom...
void ProccessCurrentState(bool bWasLerping=false, bool bThrowEvents=true, bool bCheckAutoDrop=true)
float Stiffness
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
virtual void OnRegister() override
bool bIsLocked
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
void OnEndUsed_Implementation() override
bool bDenyGripping
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface", meta = (ScriptName = "IsDen...
EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override
void OnChildGrip_Implementation(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation) override
bool bRepGameplayTags
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
void ReceiveLeverFinishedLerping(float LeverFinalAngle)
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Lever Finished Lerping"))
int GripPriority
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings")
EGripMovementReplicationSettings MovementReplicationSetting
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
bool bIsHeld
UPROPERTY(BlueprintReadOnly, Category = "VRGripInterface", meta = (ScriptName = "IsCurrentlyHeld"))
bool bIsPhysicsLever
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
float LeverMomentumFriction
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings",...
int FramesToAverage
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Momentum Settings",...
virtual void OnUnregister() override
float SecondarySlotRange
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings")
void IsHeld_Implementation(TArray< FBPGripPair > &CurHoldingControllers, bool &bCurIsHeld) override
EVRInteractibleLeverAxis LeverRotationAxis
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
float LeverLimitPositive
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent", meta = (ClampMin = "0....
ESecondaryGripType SecondaryGripType_Implementation() override
bool DenyGripping_Implementation(UGripMotionControllerComponent *GripInitiator=nullptr) override
float AngleThreshold
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Flight Stick Settings",...
bool bIsLerping
UPROPERTY(BlueprintReadOnly, Category = "VRLeverComponent")
void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent *GripOwningController, USceneComponent *ReleasingSecondaryGripComponent, const FBPActorGripInformation &GripInformation) override
bool bBlendAxisValuesByAngleThreshold
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Flight Stick Settings")
float CalcAngle(EVRInteractibleLeverAxis AxisToCalc, FVector CurInteractorLocation, bool bSkipLimits=false)
void SetLeverAngle(float NewAngle, FVector DualAxisForwardVector, bool bAllowThrowingEvents=true)
UFUNCTION(BlueprintCallable, Category = "VRLeverComponent")
void SetIsLocked(bool bNewLockedState)
UFUNCTION(BlueprintCallable, Category = "GripSettings")
void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool &bHadSlotInRange, FTransform &SlotWorldTransform, FName &SlotName, UGripMotionControllerComponent *CallingController=nullptr, FName OverridePrefix=NAME_None) override
FRotator AllCurrentLeverAngles
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
FVRLeverStateChangedSignature OnLeverStateChanged
UPROPERTY(BlueprintAssignable, Category = "VRLeverComponent")
FVROnGripSignature OnGripped
UPROPERTY(BlueprintAssignable, Category = "Grip Events")
bool RequestsSocketing_Implementation(USceneComponent *&ParentToSocketTo, FName &OptionalSocketName, FTransform_NetQuantize &RelativeTransform) override
float LeverTogglePercentage
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent", meta = (ClampMin = "0....
virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent *Controller, bool bGripped, const FBPActorGripInformation &GripInformation, bool bWasSocketed=false) override
void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override
void SetGripPriority(int NewGripPriority)
UFUNCTION(BlueprintCallable, Category = "GripSettings")
EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override
void CalculateCurrentAngle(FTransform &CurrentTransform)
float LeverReturnSpeed
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
bool GetGripScripts_Implementation(TArray< UVRGripScriptBase * > &ArrayReference) override
void OnChildGripRelease_Implementation(UGripMotionControllerComponent *ReleasingController, const FBPActorGripInformation &GripInformation, bool bWasSocketed=false) override
void OnSecondaryGrip_Implementation(UGripMotionControllerComponent *GripOwningController, USceneComponent *SecondaryGripComponent, const FBPActorGripInformation &GripInformation) override
bool bOriginalReplicatesMovement
bool AllowsMultipleGrips_Implementation() override
virtual void PreReplication(IRepChangedPropertyTracker &ChangedPropertyTracker) override
bool bUngripAtTargetRotation
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
FVector InitialInteractorLocation
void OnEndSecondaryUsed_Implementation() override
bool bSendLeverEventsDuringLerp
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
float FlightStickYawLimit
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent|Flight Stick Settings",...
float GripBreakDistance_Implementation() override
virtual void BeginPlay() override
FVector InitialInteractorDropLocation
void ReceiveLeverStateChanged(bool LeverStatus, EVRInteractibleLeverEventType LeverStatusType, float LeverAngleAtTime, float FullLeverAngleAttime)
UFUNCTION(BlueprintImplementableEvent, meta = (DisplayName = "Lever State Changed"))
FVRLeverFinishedLerpingSignature OnLeverFinishedLerping
UPROPERTY(BlueprintAssignable, Category = "VRLeverComponent")
TWeakObjectPtr< USceneComponent > ParentComponent
float Damping
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
void ResetInitialLeverLocation(bool bAllowThrowingEvents=true)
UFUNCTION(BlueprintCallable, Category = "VRLeverComponent")
bool CheckAutoDrop(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation)
FVROnDropSignature OnDropped
UPROPERTY(BlueprintAssignable, Category = "Grip Events")
FGameplayTagContainer GameplayTags
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
void SetHeld_Implementation(UGripMotionControllerComponent *NewHoldingController, uint8 GripID, bool bNewIsHeld) override
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override
float ReCalculateCurrentAngle(bool bAllowThrowingEvents=true)
UFUNCTION(BlueprintCallable, Category = "VRLeverComponent")
float CurrentLeverAngle
UPROPERTY(BlueprintReadOnly, Category = "VRLeverComponent")
bool SimulateOnDrop_Implementation() override
float BreakDistance
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
void LerpAxis(float CurrentAngle, float DeltaTime)
float PrimarySlotRange
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripSettings")
EVRInteractibleLeverReturnType LeverReturnTypeWhenReleased
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
bool bAutoDropWhenLocked
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRLeverComponent")
void GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) override
void OnSecondaryUsed_Implementation() override
EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override
FVector CurrentLeverForwardVector
UPROPERTY(BlueprintReadOnly, Category = "VRLeverComponent")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
UGripMotionControllerComponent * HoldingController
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripPair")
uint8 GripID
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "GripPair")