Update VRE

This commit is contained in:
Simeon "Waldo" Wallrath 2024-08-26 16:01:27 +02:00
parent dc6bcf82a3
commit 808b378db1
84 changed files with 3837 additions and 896 deletions

@ -1 +1 @@
Subproject commit 53b07d78ecc5f40016a287d1c7c79a80ea0ad5b5 Subproject commit 2c50d98d0de49b79602a30397dbda089b672c3b6

View file

@ -1,7 +1,7 @@
{ {
"FileVersion": 3, "FileVersion": 3,
"Version": 5.3, "Version": 5.4,
"VersionName": "5.3", "VersionName": "5.4",
"FriendlyName": "OpenXRExpansionPlugin", "FriendlyName": "OpenXRExpansionPlugin",
"Description": "An set of utility functions for OpenXR", "Description": "An set of utility functions for OpenXR",
"Category": "Virtual Reality", "Category": "Virtual Reality",
@ -31,7 +31,7 @@
{ {
"Name": "OpenXRExpansionEditor", "Name": "OpenXRExpansionEditor",
"Type": "UnCookedOnly", "Type": "UnCookedOnly",
"LoadingPhase": "PostEngineInit" "LoadingPhase": "PreDefault"
} }
], ],
"Plugins": [ "Plugins": [

View file

@ -10,6 +10,8 @@ namespace UnrealBuildTool.Rules
public OpenXRExpansionPlugin(ReadOnlyTargetRules Target) public OpenXRExpansionPlugin(ReadOnlyTargetRules Target)
: base(Target) : base(Target)
{ {
SetupIrisSupport(Target);
PublicDependencyModuleNames.AddRange( PublicDependencyModuleNames.AddRange(
new string[] new string[]
{ {

View file

@ -29,9 +29,28 @@ void FAnimNode_ApplyOpenXRHandPose::OnInitializeAnimInstance(const FAnimInstance
{ {
Super::OnInitializeAnimInstance(InProxy, InAnimInstance); Super::OnInitializeAnimInstance(InProxy, InAnimInstance);
if (const UOpenXRAnimInstance * animInst = Cast<UOpenXRAnimInstance>(InAnimInstance)) if (const UOpenXRAnimInstance * OpenXRAnimInstance = Cast<UOpenXRAnimInstance>(InAnimInstance))
{ {
bIsOpenInputAnimationInstance = true; bIsOpenInputAnimationInstance = true;
if (OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData.Num())
{
for (int i = 0; i < OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData.Num(); ++i)
{
EVRSkeletalHandIndex TargetHand = OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData[i].TargetHand;
if (OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData[i].bMirrorLeftRight)
{
TargetHand = (TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) ? EVRSkeletalHandIndex::EActionHandIndex_Right : EVRSkeletalHandIndex::EActionHandIndex_Left;
}
if (TargetHand == MappedBonePairs.TargetHand)
{
bIsMirroringHand = OpenXRAnimInstance->AnimInstanceProxy.HandSkeletalActionData[i].bMirrorLeftRight;
break;
}
}
}
} }
} }
@ -168,7 +187,16 @@ void FAnimNode_ApplyOpenXRHandPose::CalculateOpenXRAdjustment()
// Side direction // Side direction
// Do I need to flip this for left hand? // Do I need to flip this for left hand?
static FVector OpenXRSideDirection = FVector(0.f, 1.f, 0.f);
bool bUseLeftHandOffsets = false;
if ((!bIsMirroringHand && MappedBonePairs.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Left) ||
(bIsMirroringHand && MappedBonePairs.TargetHand == EVRSkeletalHandIndex::EActionHandIndex_Right))
{
bUseLeftHandOffsets = true;
}
//static FVector OpenXRSideDirection = FVector(0.f, 1.f, 0.f);
FVector OpenXRSideDirection = bUseLeftHandOffsets ? FVector(0.f, -1.f, 0.f) : FVector(0.f, 1.f, 0.f);
// Align forward vectors, openXR once in engine is X+ forward // Align forward vectors, openXR once in engine is X+ forward
FQuat AlignmentRot = FQuat::FindBetweenNormals(WristForwardLS_UE, OpenXRForwardDirection); FQuat AlignmentRot = FQuat::FindBetweenNormals(WristForwardLS_UE, OpenXRForwardDirection);
@ -380,9 +408,6 @@ void FAnimNode_ApplyOpenXRHandPose::EvaluateSkeletalControl_AnyThread(FComponent
return; return;
} }
FTransform trans = FTransform::Identity; FTransform trans = FTransform::Identity;
OutBoneTransforms.Reserve(MappedBonePairs.BonePairs.Num()); OutBoneTransforms.Reserve(MappedBonePairs.BonePairs.Num());
TArray<FBoneTransform> TransBones; TArray<FBoneTransform> TransBones;

View file

@ -6,6 +6,7 @@
#include "MotionControllerComponent.h" #include "MotionControllerComponent.h"
#include "OpenXRExpansionFunctionLibrary.h" #include "OpenXRExpansionFunctionLibrary.h"
#include "Engine/NetSerialization.h" #include "Engine/NetSerialization.h"
#include "Net/Core/PushModel/PushModel.h"
#include "XRMotionControllerBase.h" // for GetHandEnumForSourceName() #include "XRMotionControllerBase.h" // for GetHandEnumForSourceName()
//#include "EngineMinimal.h" //#include "EngineMinimal.h"
@ -29,9 +30,13 @@ void UOpenXRHandPoseComponent::GetLifetimeReplicatedProps(TArray< class FLifetim
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
FDoRepLifetimeParams SkipOwnerParams;
SkipOwnerParams.Condition = COND_SkipOwner;
SkipOwnerParams.bIsPushBased = true;
// Skipping the owner with this as the owner will use the controllers location directly // Skipping the owner with this as the owner will use the controllers location directly
DOREPLIFETIME_CONDITION(UOpenXRHandPoseComponent, LeftHandRep, COND_SkipOwner); DOREPLIFETIME_WITH_PARAMS_FAST(UOpenXRHandPoseComponent, LeftHandRep, SkipOwnerParams);
DOREPLIFETIME_CONDITION(UOpenXRHandPoseComponent, RightHandRep, COND_SkipOwner); DOREPLIFETIME_WITH_PARAMS_FAST(UOpenXRHandPoseComponent, RightHandRep, SkipOwnerParams);
} }
void UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Implementation(const FBPXRSkeletalRepContainer& SkeletalInfo) void UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Implementation(const FBPXRSkeletalRepContainer& SkeletalInfo)
@ -49,6 +54,9 @@ void UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Implementation(cons
FBPXRSkeletalRepContainer::CopyReplicatedTo(SkeletalInfo, HandSkeletalActions[i]); FBPXRSkeletalRepContainer::CopyReplicatedTo(SkeletalInfo, HandSkeletalActions[i]);
LeftHandRep = SkeletalInfo; LeftHandRep = SkeletalInfo;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UOpenXRHandPoseComponent, LeftHandRep, this);
#endif
if (bSmoothReplicatedSkeletalData) if (bSmoothReplicatedSkeletalData)
{ {
@ -64,6 +72,9 @@ void UOpenXRHandPoseComponent::Server_SendSkeletalTransforms_Implementation(cons
FBPXRSkeletalRepContainer::CopyReplicatedTo(SkeletalInfo, HandSkeletalActions[i]); FBPXRSkeletalRepContainer::CopyReplicatedTo(SkeletalInfo, HandSkeletalActions[i]);
RightHandRep = SkeletalInfo; RightHandRep = SkeletalInfo;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UOpenXRHandPoseComponent, RightHandRep, this);
#endif
if (bSmoothReplicatedSkeletalData) if (bSmoothReplicatedSkeletalData)
{ {

View file

@ -42,7 +42,8 @@ public:
UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinHiddenByDefault)) UPROPERTY(EditAnywhere, Category = Skeletal, meta = (PinHiddenByDefault))
FBPOpenXRSkeletalMappingData MappedBonePairs; FBPOpenXRSkeletalMappingData MappedBonePairs;
bool bIsOpenInputAnimationInstance; bool bIsOpenInputAnimationInstance = false;
bool bIsMirroringHand = false;
void ConvertHandTransformsSpace(TArray<FTransform>& OutTransforms, const TArray<FTransform>& WorldTransforms, FTransform AddTrans, bool bMirrorLeftRight, bool bMergeMissingUE4Bones); void ConvertHandTransformsSpace(TArray<FTransform>& OutTransforms, const TArray<FTransform>& WorldTransforms, FTransform AddTrans, bool bMirrorLeftRight, bool bMergeMissingUE4Bones);

View file

@ -103,7 +103,7 @@ public:
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
bool bAllowDeformingMesh; bool bAllowDeformingMesh;
// If true then the bones will be mirrored from left/right, to allow you to swap a hand mesh or apply to a full body mesh // If true then the bones will be mirrored from left/right, to allow you to swap a hand mesh to the other hand
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default) UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadWrite, Category = Default)
bool bMirrorLeftRight; bool bMirrorLeftRight;

View file

@ -1,4 +1,4 @@
UE4 Forums Thread UE Forums Thread
https://forums.unrealengine.com/development-discussion/vr-ar-development/89050-vr-openvr-expansion-plugin https://forums.unrealengine.com/development-discussion/vr-ar-development/89050-vr-openvr-expansion-plugin
Example Template Project Example Template Project

View file

@ -96,9 +96,20 @@ bool FHandSocketVisualizer::GetCustomInputCoordinateSystem(const FEditorViewport
else else
{ {
if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent())
{
if (IsValid(CurrentlyEditingComponent->HandVisualizerComponent))
{ {
FTransform newTrans = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx); FTransform newTrans = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx);
OutMatrix = FRotationMatrix::Make(newTrans.GetRotation()); FQuat Rot = newTrans.GetRotation();
if (!newTrans.GetRotation().ContainsNaN())
{
Rot.Normalize();
OutMatrix = FRotationMatrix::Make(Rot);
return true;
}
}
return false;
} }
} }
@ -126,7 +137,7 @@ void FHandSocketVisualizer::DrawVisualizationHUD(const UActorComponent* Componen
{ {
if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent())
{ {
if (!CurrentlyEditingComponent->HandVisualizerComponent) if (!IsValid(CurrentlyEditingComponent->HandVisualizerComponent))
{ {
return; return;
} }
@ -142,6 +153,7 @@ void FHandSocketVisualizer::DrawVisualizationHUD(const UActorComponent* Componen
const float DrawPositionX = FMath::FloorToFloat(CanvasRect.Min.X + (CanvasRect.Width() - XL) * 0.5f); const float DrawPositionX = FMath::FloorToFloat(CanvasRect.Min.X + (CanvasRect.Width() - XL) * 0.5f);
const float DrawPositionY = CanvasRect.Min.Y + 50.0f; const float DrawPositionY = CanvasRect.Min.Y + 50.0f;
Canvas->DrawShadowedString(DrawPositionX, DrawPositionY, *CurrentlySelectedBone.ToString(), GEngine->GetLargeFont(), FLinearColor::Yellow); Canvas->DrawShadowedString(DrawPositionX, DrawPositionY, *CurrentlySelectedBone.ToString(), GEngine->GetLargeFont(), FLinearColor::Yellow);
} }
} }
} }
@ -309,9 +321,16 @@ bool FHandSocketVisualizer::GetWidgetLocation(const FEditorViewportClient* Viewp
else else
{ {
if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent()) if (UHandSocketComponent* CurrentlyEditingComponent = GetCurrentlyEditingComponent())
{
if (IsValid(CurrentlyEditingComponent->HandVisualizerComponent))
{ {
OutLocation = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx).GetLocation(); OutLocation = CurrentlyEditingComponent->HandVisualizerComponent->GetBoneTransform(CurrentlySelectedBoneIdx).GetLocation();
} }
else
{
return false;
}
}
} }
return true; return true;

View file

@ -31,6 +31,8 @@
#include "AssetRegistry/AssetRegistryModule.h" #include "AssetRegistry/AssetRegistryModule.h"
#include "AssetRegistry/ARFilter.h" #include "AssetRegistry/ARFilter.h"
#include "FileHelpers.h"
#include "Engine/Engine.h"
#include "Editor/UnrealEdEngine.h" #include "Editor/UnrealEdEngine.h"
#include "UnrealEdGlobals.h" #include "UnrealEdGlobals.h"
@ -76,8 +78,60 @@ void FVRGlobalSettingsDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuil
.Text(LOCTEXT("FixInvalidAnimationAssetsButton", "Fix Animation Assets")) .Text(LOCTEXT("FixInvalidAnimationAssetsButton", "Fix Animation Assets"))
] ]
]; ];
/*DetailBuilder.EditCategory("Utilities")
.AddCustomRow(LOCTEXT("Fix 5.4.0 Shadow Shader", "Fix Broken 5.4.0 Shadow Shader"))
.NameContent()
[
SNew(STextBlock)
.Font(IDetailLayoutBuilder::GetDetailFont())
.Text(LOCTEXT("Fix54ShadowShader", "Fix Broken 5.4.0 Shadow Shader"))
]
.ValueContent()
.MaxDesiredWidth(125.f)
.MinDesiredWidth(125.f)
[
SNew(SButton)
.ContentPadding(2)
.VAlign(VAlign_Center)
.HAlign(HAlign_Center)
.OnClicked(this, &FVRGlobalSettingsDetails::OnFixShadowShader)
[
SNew(STextBlock)
.Font(IDetailLayoutBuilder::GetDetailFont())
.Text(LOCTEXT("Fix54ShadowShaderButton", "Fix Broken 5.4.0 Shadow Shader"))
]
];*/
} }
/*FReply FVRGlobalSettingsDetails::OnFixShadowShader()
{
#if ENGINE_MAJOR_VERSION == 5 && ENGINE_MINOR_VERSION == 4
FString EnginePath = FPaths::EngineDir();
EnginePath += "/Shaders/Private/ShadowProjectionPixelShader.usf";
if (FPlatformFileManager::Get().GetPlatformFile().FileExists(*EnginePath))
{
FString FileStr = "";
if (FFileHelper::LoadFileToString(FileStr, *EnginePath))
{
// Don't need to do anything complicated, the shader only contains one line with this define in it
FileStr = FileStr.Replace(TEXT("#if MOBILE_MULTI_VIEW || INSTANCED_STEREO"),TEXT("#if ((MOBILE_MULTI_VIEW || INSTANCED_STEREO) && SHADING_PATH_MOBILE)"));
FFileHelper::SaveStringToFile(FileStr, *EnginePath);
GEngine->Exec(GEngine->GetWorld(), TEXT("recompileshaders changed"));
UE_LOG(LogPath, Log, TEXT("ShadowProjectionPixelShader.usf resaved and recompiled!"));
return FReply::Handled();
}
}
#endif
UE_LOG(LogPath, Error, TEXT("ShadowProjectionPixelShader.usf could not be found, edited, or the engine version is incorrect!"));
return FReply::Handled();
}*/
FReply FVRGlobalSettingsDetails::OnCorrectInvalidAnimationAssets() FReply FVRGlobalSettingsDetails::OnCorrectInvalidAnimationAssets()
{ {

View file

@ -21,6 +21,8 @@ public:
FReply OnCorrectInvalidAnimationAssets(); FReply OnCorrectInvalidAnimationAssets();
FReply OnFixShadowShader();
void OnLockedStateUpdated(IDetailLayoutBuilder* LayoutBuilder); void OnLockedStateUpdated(IDetailLayoutBuilder* LayoutBuilder);

View file

@ -118,7 +118,7 @@ void FSavedMove_VRBaseCharacter::SetInitialPosition(ACharacter* C)
// Instead, re-purpose it to be the capsule half height // Instead, re-purpose it to be the capsule half height
if (AVRBaseCharacter* BaseChar = Cast<AVRBaseCharacter>(C)) if (AVRBaseCharacter* BaseChar = Cast<AVRBaseCharacter>(C))
{ {
if (BaseChar->VRReplicateCapsuleHeight) if (BaseChar->GetVRReplicateCapsuleHeight())
CapsuleHeight = BaseChar->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight(); CapsuleHeight = BaseChar->GetCapsuleComponent()->GetUnscaledCapsuleHalfHeight();
else else
CapsuleHeight = 0.0f; CapsuleHeight = 0.0f;

View file

@ -57,6 +57,10 @@
#include "Features/IModularFeatures.h" #include "Features/IModularFeatures.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
DEFINE_LOG_CATEGORY(LogVRMotionController); DEFINE_LOG_CATEGORY(LogVRMotionController);
//For UE4 Profiler ~ Stat //For UE4 Profiler ~ Stat
DECLARE_CYCLE_STAT(TEXT("TickGrip ~ TickingGrip"), STAT_TickGrip, STATGROUP_TickGrip); DECLARE_CYCLE_STAT(TEXT("TickGrip ~ TickingGrip"), STAT_TickGrip, STATGROUP_TickGrip);
@ -666,17 +670,25 @@ void UGripMotionControllerComponent::GetLifetimeReplicatedProps(TArray< class FL
DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeRotation); DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeRotation);
DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D); DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D);
// For std properties
FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, GrippedObjects, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, ControllerNetUpdateRate, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, bSmoothReplicatedMotion, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, bReplicateWithoutTracking, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_SkipOwner, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
// Skipping the owner with this as the owner will use the controllers location directly // Skipping the owner with this as the owner will use the controllers location directly
DOREPLIFETIME_CONDITION(UGripMotionControllerComponent, ReplicatedControllerTransform, COND_SkipOwner); DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, ReplicatedControllerTransform, PushModelParamsWithCondition);
DOREPLIFETIME(UGripMotionControllerComponent, GrippedObjects); DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, LocallyGrippedObjects, PushModelParamsWithCondition);
DOREPLIFETIME(UGripMotionControllerComponent, ControllerNetUpdateRate);
DOREPLIFETIME(UGripMotionControllerComponent, bSmoothReplicatedMotion);
DOREPLIFETIME(UGripMotionControllerComponent, bReplicateWithoutTracking);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithConditionOwnerOnly{ COND_OwnerOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_CONDITION(UGripMotionControllerComponent, LocallyGrippedObjects, COND_SkipOwner); DOREPLIFETIME_WITH_PARAMS_FAST(UGripMotionControllerComponent, LocalTransactionBuffer, PushModelParamsWithConditionOwnerOnly);
DOREPLIFETIME_CONDITION(UGripMotionControllerComponent, LocalTransactionBuffer, COND_OwnerOnly);
// DOREPLIFETIME(UGripMotionControllerComponent, bReplicateControllerTransform); // DOREPLIFETIME(UGripMotionControllerComponent, bReplicateControllerTransform);
} }
@ -694,6 +706,9 @@ void UGripMotionControllerComponent::Server_SendControllerTransform_Implementati
{ {
// Store new transform and trigger OnRep_Function // Store new transform and trigger OnRep_Function
ReplicatedControllerTransform = NewTransform; ReplicatedControllerTransform = NewTransform;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, ReplicatedControllerTransform, this);
#endif
// Server should no longer call this RPC itself, but if is using non tracked then it will so keeping auth check // Server should no longer call this RPC itself, but if is using non tracked then it will so keeping auth check
if(!bHasAuthority) if(!bHasAuthority)
@ -732,6 +747,14 @@ void UGripMotionControllerComponent::GetPhysicsVelocities(const FBPActorGripInfo
return; return;
} }
// TMP #TODO: Fix when 5.4 bug is fixed
if (!primComp->IsSimulatingPhysics())
{
CurLinearVelocity = Grip.LinVel;
CurAngularVelocity = Grip.RotVel;
return;
}
CurAngularVelocity = primComp->GetPhysicsAngularVelocityInDegrees(); CurAngularVelocity = primComp->GetPhysicsAngularVelocityInDegrees();
CurLinearVelocity = primComp->GetPhysicsLinearVelocity(); CurLinearVelocity = primComp->GetPhysicsLinearVelocity();
} }
@ -1031,6 +1054,7 @@ void UGripMotionControllerComponent::SetGripCollisionType(const FBPActorGripInfo
{ {
GrippedObjects[fIndex].GripCollisionType = NewGripCollisionType; GrippedObjects[fIndex].GripCollisionType = NewGripCollisionType;
ReCreateGrip(GrippedObjects[fIndex]); ReCreateGrip(GrippedObjects[fIndex]);
DIRTY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
} }
@ -1049,6 +1073,7 @@ void UGripMotionControllerComponent::SetGripCollisionType(const FBPActorGripInfo
} }
ReCreateGrip(LocallyGrippedObjects[fIndex]); ReCreateGrip(LocallyGrippedObjects[fIndex]);
DIRTY_LOCALLY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
@ -1065,6 +1090,7 @@ void UGripMotionControllerComponent::SetGripLateUpdateSetting(const FBPActorGrip
if (fIndex != INDEX_NONE) if (fIndex != INDEX_NONE)
{ {
GrippedObjects[fIndex].GripLateUpdateSetting = NewGripLateUpdateSetting; GrippedObjects[fIndex].GripLateUpdateSetting = NewGripLateUpdateSetting;
DIRTY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
} }
@ -1082,6 +1108,7 @@ void UGripMotionControllerComponent::SetGripLateUpdateSetting(const FBPActorGrip
Server_NotifyLocalGripAddedOrChanged(GripInfo); Server_NotifyLocalGripAddedOrChanged(GripInfo);
} }
DIRTY_LOCALLY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
} }
@ -1107,6 +1134,8 @@ void UGripMotionControllerComponent::SetGripRelativeTransform(
NotifyGripTransformChanged(Grip); NotifyGripTransformChanged(Grip);
} }
DIRTY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
} }
@ -1129,6 +1158,8 @@ void UGripMotionControllerComponent::SetGripRelativeTransform(
Server_NotifyLocalGripAddedOrChanged(GripInfo); Server_NotifyLocalGripAddedOrChanged(GripInfo);
} }
DIRTY_LOCALLY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
} }
@ -1148,6 +1179,7 @@ void UGripMotionControllerComponent::SetGripAdditionTransform(
if (fIndex != INDEX_NONE) if (fIndex != INDEX_NONE)
{ {
GrippedObjects[fIndex].AdditionTransform = CreateGripRelativeAdditionTransform(Grip, NewAdditionTransform, bMakeGripRelative); GrippedObjects[fIndex].AdditionTransform = CreateGripRelativeAdditionTransform(Grip, NewAdditionTransform, bMakeGripRelative);
DIRTY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
@ -1159,6 +1191,7 @@ void UGripMotionControllerComponent::SetGripAdditionTransform(
if (fIndex != INDEX_NONE) if (fIndex != INDEX_NONE)
{ {
LocallyGrippedObjects[fIndex].AdditionTransform = CreateGripRelativeAdditionTransform(Grip, NewAdditionTransform, bMakeGripRelative); LocallyGrippedObjects[fIndex].AdditionTransform = CreateGripRelativeAdditionTransform(Grip, NewAdditionTransform, bMakeGripRelative);
DIRTY_LOCALLY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
return; return;
@ -1187,6 +1220,8 @@ void UGripMotionControllerComponent::SetGripStiffnessAndDamping(
GrippedObjects[fIndex].AdvancedGripSettings.PhysicsSettings.AngularDamping = OptionalAngularDamping; GrippedObjects[fIndex].AdvancedGripSettings.PhysicsSettings.AngularDamping = OptionalAngularDamping;
} }
DIRTY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
SetGripConstraintStiffnessAndDamping(&GrippedObjects[fIndex]); SetGripConstraintStiffnessAndDamping(&GrippedObjects[fIndex]);
//return; //return;
@ -1212,6 +1247,8 @@ void UGripMotionControllerComponent::SetGripStiffnessAndDamping(
Server_NotifyLocalGripAddedOrChanged(GripInfo); Server_NotifyLocalGripAddedOrChanged(GripInfo);
} }
DIRTY_LOCALLY_GRIPPED_OBJECTS();
Result = EBPVRResultSwitch::OnSucceeded; Result = EBPVRResultSwitch::OnSucceeded;
SetGripConstraintStiffnessAndDamping(&LocallyGrippedObjects[fIndex]); SetGripConstraintStiffnessAndDamping(&LocallyGrippedObjects[fIndex]);
// return; // return;
@ -1710,6 +1747,8 @@ bool UGripMotionControllerComponent::GripActor(
if (!bIsLocalGrip) if (!bIsLocalGrip)
{ {
int32 Index = GrippedObjects.Add(newActorGrip); int32 Index = GrippedObjects.Add(newActorGrip);
DIRTY_GRIPPED_OBJECTS();
if (Index != INDEX_NONE) if (Index != INDEX_NONE)
NotifyGrip(GrippedObjects[Index]); NotifyGrip(GrippedObjects[Index]);
//NotifyGrip(newActorGrip); //NotifyGrip(newActorGrip);
@ -1719,9 +1758,13 @@ bool UGripMotionControllerComponent::GripActor(
if (!IsLocallyControlled()) if (!IsLocallyControlled())
{ {
LocalTransactionBuffer.Add(newActorGrip); LocalTransactionBuffer.Add(newActorGrip);
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this);
#endif
} }
int32 Index = LocallyGrippedObjects.Add(newActorGrip); int32 Index = LocallyGrippedObjects.Add(newActorGrip);
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (Index != INDEX_NONE) if (Index != INDEX_NONE)
{ {
@ -1966,6 +2009,8 @@ bool UGripMotionControllerComponent::GripComponent(
if (!bIsLocalGrip) if (!bIsLocalGrip)
{ {
int32 Index = GrippedObjects.Add(newComponentGrip); int32 Index = GrippedObjects.Add(newComponentGrip);
DIRTY_GRIPPED_OBJECTS();
if (Index != INDEX_NONE) if (Index != INDEX_NONE)
NotifyGrip(GrippedObjects[Index]); NotifyGrip(GrippedObjects[Index]);
@ -1976,9 +2021,13 @@ bool UGripMotionControllerComponent::GripComponent(
if (!IsLocallyControlled()) if (!IsLocallyControlled())
{ {
LocalTransactionBuffer.Add(newComponentGrip); LocalTransactionBuffer.Add(newComponentGrip);
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this);
#endif
} }
int32 Index = LocallyGrippedObjects.Add(newComponentGrip); int32 Index = LocallyGrippedObjects.Add(newComponentGrip);
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (Index != INDEX_NONE) if (Index != INDEX_NONE)
{ {
@ -2083,6 +2132,9 @@ bool UGripMotionControllerComponent::DropGrip_Implementation(const FBPActorGripI
if (LocalTransactionBuffer[i].GripID == Grip.GripID) if (LocalTransactionBuffer[i].GripID == Grip.GripID)
LocalTransactionBuffer.RemoveAt(i); LocalTransactionBuffer.RemoveAt(i);
} }
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this);
#endif
} }
UPrimitiveComponent * PrimComp = nullptr; UPrimitiveComponent * PrimComp = nullptr;
@ -2699,6 +2751,8 @@ void UGripMotionControllerComponent::DropAndSocket_Implementation(const FBPActor
int fIndex = 0; int fIndex = 0;
if (LocallyGrippedObjects.Find(NewDrop, fIndex)) if (LocallyGrippedObjects.Find(NewDrop, fIndex))
{ {
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (HasGripAuthority(NewDrop) || IsServer()) if (HasGripAuthority(NewDrop) || IsServer())
{ {
LocallyGrippedObjects.RemoveAt(fIndex); LocallyGrippedObjects.RemoveAt(fIndex);
@ -2714,6 +2768,7 @@ void UGripMotionControllerComponent::DropAndSocket_Implementation(const FBPActor
fIndex = 0; fIndex = 0;
if (GrippedObjects.Find(NewDrop, fIndex)) if (GrippedObjects.Find(NewDrop, fIndex))
{ {
DIRTY_GRIPPED_OBJECTS();
if (HasGripAuthority(NewDrop) || IsServer()) if (HasGripAuthority(NewDrop) || IsServer())
{ {
GrippedObjects.RemoveAt(fIndex); GrippedObjects.RemoveAt(fIndex);
@ -3069,7 +3124,7 @@ bool UGripMotionControllerComponent::NotifyGrip(FBPActorGripInformation &NewGrip
case EGripCollisionType::AttachmentGrip: case EGripCollisionType::AttachmentGrip:
{ {
if (root) if (IsValid(root))
root->SetSimulatePhysics(false); root->SetSimulatePhysics(false);
// Move it to the correct location automatically // Move it to the correct location automatically
@ -3096,7 +3151,7 @@ bool UGripMotionControllerComponent::NotifyGrip(FBPActorGripInformation &NewGrip
default: default:
{ {
if (root) if (IsValid(root))
{ {
if (root->IsSimulatingPhysics()) if (root->IsSimulatingPhysics())
{ {
@ -3129,6 +3184,13 @@ bool UGripMotionControllerComponent::NotifyGrip(FBPActorGripInformation &NewGrip
if (!bIsReInit) if (!bIsReInit)
{ {
// TMP #TODO: Remove when 5.4 velocity bug is fixed
if (IsValid(root))
{
// Set initial world transform for velocity
NewGrip.LastVelWorldTrans = root->GetComponentTransform();
}
// Broadcast a new grip // Broadcast a new grip
OnGrippedObject.Broadcast(NewGrip); OnGrippedObject.Broadcast(NewGrip);
if (!LocallyGrippedObjects.Contains(NewGrip.GripID) && !GrippedObjects.Contains(NewGrip.GripID)) if (!LocallyGrippedObjects.Contains(NewGrip.GripID) && !GrippedObjects.Contains(NewGrip.GripID))
@ -3724,15 +3786,14 @@ void UGripMotionControllerComponent::Drop_Implementation(const FBPActorGripInfor
}; };
// Copy over the information instead of working with a reference for the OnDroppedBroadcast // Copy over the information instead of working with a reference for the OnDroppedBroadcast
FBPActorGripInformation DropBroadcastData = NewDrop; FBPActorGripInformation DropBroadcastData = NewDrop;
int fIndex = 0; int fIndex = 0;
if (LocallyGrippedObjects.Find(NewDrop, fIndex)) if (LocallyGrippedObjects.Find(NewDrop, fIndex))
{ {
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (HasGripAuthority(NewDrop) || IsServer()) if (HasGripAuthority(NewDrop) || IsServer())
{ {
LocallyGrippedObjects.RemoveAt(fIndex); LocallyGrippedObjects.RemoveAt(fIndex);
@ -3748,6 +3809,7 @@ void UGripMotionControllerComponent::Drop_Implementation(const FBPActorGripInfor
fIndex = 0; fIndex = 0;
if (GrippedObjects.Find(NewDrop, fIndex)) if (GrippedObjects.Find(NewDrop, fIndex))
{ {
DIRTY_GRIPPED_OBJECTS();
if (HasGripAuthority(NewDrop) || IsServer()) if (HasGripAuthority(NewDrop) || IsServer())
{ {
GrippedObjects.RemoveAt(fIndex); GrippedObjects.RemoveAt(fIndex);
@ -4024,6 +4086,15 @@ bool UGripMotionControllerComponent::AddSecondaryAttachmentToGrip(const FBPActor
Server_NotifySecondaryAttachmentChanged(GripToUse->GripID, GripToUse->SecondaryGripInfo); Server_NotifySecondaryAttachmentChanged(GripToUse->GripID, GripToUse->SecondaryGripInfo);
} }
if (bWasLocal)
{
DIRTY_LOCALLY_GRIPPED_OBJECTS();
}
else
{
DIRTY_GRIPPED_OBJECTS();
}
OnSecondaryGripAdded.Broadcast(*GripToUse); OnSecondaryGripAdded.Broadcast(*GripToUse);
GripToUse = nullptr; GripToUse = nullptr;
@ -4214,6 +4285,15 @@ bool UGripMotionControllerComponent::RemoveSecondaryAttachmentFromGrip(const FBP
} }
if (bWasLocal)
{
DIRTY_LOCALLY_GRIPPED_OBJECTS();
}
else
{
DIRTY_GRIPPED_OBJECTS();
}
SecondaryGripIDs.Remove(GripToUse->GripID); SecondaryGripIDs.Remove(GripToUse->GripID);
OnSecondaryGripRemoved.Broadcast(*GripToUse); OnSecondaryGripRemoved.Broadcast(*GripToUse);
GripToUse = nullptr; GripToUse = nullptr;
@ -4532,6 +4612,10 @@ bool UGripMotionControllerComponent::TeleportMoveGrip_Impl(FBPActorGripInformati
} }
} }
// TMP #TODO: Remove with 5.4 bug with velocity is fixed
// Reset our last world transform velocity as typically we don't want to accumulate teleport speeds into it.
Grip.LastVelWorldTrans = PrimComp->GetComponentTransform();
return true; return true;
} }
@ -4727,6 +4811,10 @@ void UGripMotionControllerComponent::UpdateTracking(float DeltaTime)
ReplicatedControllerTransform.Position = RelLoc; ReplicatedControllerTransform.Position = RelLoc;
ReplicatedControllerTransform.Rotation = RelRot; ReplicatedControllerTransform.Rotation = RelRot;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, ReplicatedControllerTransform, this);
#endif
// I would keep the torn off check here, except this can be checked on tick if they // I would keep the torn off check here, except this can be checked on tick if they
// Set 100 htz updates, and in the TornOff case, it actually can't hurt any besides some small // Set 100 htz updates, and in the TornOff case, it actually can't hurt any besides some small
// Perf difference. // Perf difference.
@ -5003,6 +5091,22 @@ FVector UGripMotionControllerComponent::GetComponentVelocity() const
return Super::GetComponentVelocity(); return Super::GetComponentVelocity();
} }
// TEMP: #TODO: Remove
void UGripMotionControllerComponent::CalculateGripVelocity(FBPActorGripInformation& GripToFill, UPrimitiveComponent* ComponentToSample, float DeltaTime)
{
if (!bHasAuthority && !IsServer())
{
return;
}
FTransform CurTrans = ComponentToSample->GetComponentTransform();
GripToFill.LinVel = (CurTrans.GetLocation() - GripToFill.LastVelWorldTrans.GetLocation()) / DeltaTime;
GripToFill.RotVel = FVector::RadiansToDegrees(((CurTrans.GetRotation().ToRotationVector() - GripToFill.LastVelWorldTrans.GetRotation().ToRotationVector()))) / DeltaTime;
GripToFill.LastVelWorldTrans = CurTrans;
}
void UGripMotionControllerComponent::HandleGripArray(TArray<FBPActorGripInformation> &GrippedObjectsArray, const FTransform & ParentTransform, float DeltaTime, bool bReplicatedArray) void UGripMotionControllerComponent::HandleGripArray(TArray<FBPActorGripInformation> &GrippedObjectsArray, const FTransform & ParentTransform, float DeltaTime, bool bReplicatedArray)
{ {
if (GrippedObjectsArray.Num()) if (GrippedObjectsArray.Num())
@ -5090,6 +5194,8 @@ void UGripMotionControllerComponent::HandleGripArray(TArray<FBPActorGripInformat
else if(bActorHasInterface) else if(bActorHasInterface)
IVRGripInterface::Execute_TickGrip(actor, this, *Grip, DeltaTime); IVRGripInterface::Execute_TickGrip(actor, this, *Grip, DeltaTime);
// TEMP 5.4 (or fixed)
CalculateGripVelocity(*Grip, root, DeltaTime);
continue; continue;
} }
@ -5844,6 +5950,9 @@ void UGripMotionControllerComponent::HandleGripArray(TArray<FBPActorGripInformat
{}break; {}break;
} }
// TEMP 5.4 (or fixed)
CalculateGripVelocity(*Grip, root, DeltaTime); // Technically for physical grips it would be post physics thre
// We only do this if specifically requested, it has a slight perf hit and isn't normally needed for non Custom Grip types // We only do this if specifically requested, it has a slight perf hit and isn't normally needed for non Custom Grip types
if (bAlwaysSendTickGrip) if (bAlwaysSendTickGrip)
{ {
@ -5991,7 +6100,7 @@ bool UGripMotionControllerComponent::UpdatePhysicsHandle(const FBPActorGripInfor
return true; return true;
//#endif //#endif
return false; //return false;
} }
bool UGripMotionControllerComponent::PausePhysicsHandle(FBPActorPhysicsHandleInformation* HandleInfo) bool UGripMotionControllerComponent::PausePhysicsHandle(FBPActorPhysicsHandleInformation* HandleInfo)
@ -6400,7 +6509,7 @@ bool UGripMotionControllerComponent::SetUpPhysicsHandle(const FBPActorGripInform
using namespace Chaos; using namespace Chaos;
// Missing from physx, not sure how it is working for them currently. // Missing from physx, not sure how it is working for them currently.
//TArray<FPhysicsActorHandle> ActorHandles; //TArray<FPhysicsActorHandle> ActorHandles;
HandleInfo->KinActorData2->GetGameThreadAPI().SetGeometry(TUniquePtr<FImplicitObject>(new TSphere<FReal, 3>(TVector<FReal, 3>(0.f), 1000.f))); HandleInfo->KinActorData2->GetGameThreadAPI().SetGeometry(MakeImplicitObjectPtr<TSphere<FReal, 3>>(TVector<FReal, 3>(0.f), 1000.f));
HandleInfo->KinActorData2->GetGameThreadAPI().SetObjectState(EObjectStateType::Kinematic); HandleInfo->KinActorData2->GetGameThreadAPI().SetObjectState(EObjectStateType::Kinematic);
FPhysicsInterface::AddActorToSolver(HandleInfo->KinActorData2, ActorParams.Scene->GetSolver()); FPhysicsInterface::AddActorToSolver(HandleInfo->KinActorData2, ActorParams.Scene->GetSolver());
//ActorHandles.Add(HandleInfo->KinActorData2); //ActorHandles.Add(HandleInfo->KinActorData2);
@ -6536,7 +6645,7 @@ bool UGripMotionControllerComponent::SetUpPhysicsHandle(const FBPActorGripInform
NewLinDrive.Stiffness = Stiffness; NewLinDrive.Stiffness = Stiffness;
NewLinDrive.MaxForce = MaxForce; NewLinDrive.MaxForce = MaxForce;
HandleInfo->LinConstraint.bEnablePositionDrive = true; //HandleInfo->LinConstraint.bEnablePositionDrive = true;
HandleInfo->LinConstraint.XDrive = NewLinDrive; HandleInfo->LinConstraint.XDrive = NewLinDrive;
HandleInfo->LinConstraint.YDrive = NewLinDrive; HandleInfo->LinConstraint.YDrive = NewLinDrive;
HandleInfo->LinConstraint.ZDrive = NewLinDrive; HandleInfo->LinConstraint.ZDrive = NewLinDrive;
@ -6608,7 +6717,11 @@ bool UGripMotionControllerComponent::SetUpPhysicsHandle(const FBPActorGripInform
NewAngDrive.MaxForce = AngularMaxForce; NewAngDrive.MaxForce = AngularMaxForce;
//NewAngDrive.MaxForce = MAX_FLT; //NewAngDrive.MaxForce = MAX_FLT;
HandleInfo->LinConstraint.bEnablePositionDrive = true; //HandleInfo->LinConstraint.bEnablePositionDrive = true;
HandleInfo->LinConstraint.XDrive.bEnablePositionDrive = true;
HandleInfo->LinConstraint.YDrive.bEnablePositionDrive = true;
HandleInfo->LinConstraint.ZDrive.bEnablePositionDrive = true;
HandleInfo->LinConstraint.XDrive = NewLinDrive; HandleInfo->LinConstraint.XDrive = NewLinDrive;
HandleInfo->LinConstraint.YDrive = NewLinDrive; HandleInfo->LinConstraint.YDrive = NewLinDrive;
HandleInfo->LinConstraint.ZDrive = NewLinDrive; HandleInfo->LinConstraint.ZDrive = NewLinDrive;
@ -7202,6 +7315,27 @@ bool UGripMotionControllerComponent::GripPollControllerState_GameThread(FVector&
bPolledHMD_GameThread = false; bPolledHMD_GameThread = false;
} }
// #NOTE: This was adding in 4.20, I presume to allow for HMDs as tracking sources for mixed reality.
// Skipping all of my special logic here for now
if (MotionSource == IMotionController::HMDSourceId || MotionSource == IMotionController::HeadSourceId)
{
IXRTrackingSystem* TrackingSys = GEngine->XRSystem.Get();
if (TrackingSys)
{
FQuat OrientationQuat;
if (TrackingSys->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, OrientationQuat, Position))
{
Orientation = OrientationQuat.Rotator();
{
FScopeLock Lock(&PolledMotionControllerMutex);
bPolledHMD_GameThread = true; // We only want a render thread update from the hmd if we polled it on the game thread.
}
return true;
}
}
}
else
{
//GripUEMotionController::FScopeLockOptional LockOptional; //GripUEMotionController::FScopeLockOptional LockOptional;
TArray<IMotionController*> MotionControllers; TArray<IMotionController*> MotionControllers;
MotionControllers = IModularFeatures::Get().GetModularFeatureImplementations<IMotionController>(IMotionController::GetModularFeatureName()); MotionControllers = IModularFeatures::Get().GetModularFeatureImplementations<IMotionController>(IMotionController::GetModularFeatureName());
@ -7214,6 +7348,10 @@ bool UGripMotionControllerComponent::GripPollControllerState_GameThread(FVector&
if (bIsInGameThread) if (bIsInGameThread)
{ {
EControllerHand HandType;
GetHandType(HandType);
FName GripSource = (HandType == EControllerHand::Left) ? FName("LeftGrip") : FName("RightGrip");
CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, MotionSource); CurrentTrackingStatus = MotionController->GetControllerTrackingStatus(PlayerIndex, MotionSource);
if (!bIgnoreTrackingStatus && CurrentTrackingStatus == ETrackingStatus::NotTracked) if (!bIgnoreTrackingStatus && CurrentTrackingStatus == ETrackingStatus::NotTracked)
continue; continue;
@ -7270,25 +7408,6 @@ bool UGripMotionControllerComponent::GripPollControllerState_GameThread(FVector&
} }
#endif*/ #endif*/
} }
// #NOTE: This was adding in 4.20, I presume to allow for HMDs as tracking sources for mixed reality.
// Skipping all of my special logic here for now
if (MotionSource == IMotionController::HMDSourceId)
{
IXRTrackingSystem* TrackingSys = GEngine->XRSystem.Get();
if (TrackingSys)
{
FQuat OrientationQuat;
if (TrackingSys->GetCurrentPose(IXRTrackingSystem::HMDDeviceId, OrientationQuat, Position))
{
Orientation = OrientationQuat.Rotator();
{
FScopeLock Lock(&PolledMotionControllerMutex);
bPolledHMD_GameThread = true; // We only want a render thread update from the hmd if we polled it on the game thread.
}
return true;
}
}
} }
} }
return false; return false;
@ -7301,7 +7420,11 @@ bool UGripMotionControllerComponent::GripPollControllerState_RenderThread(FVecto
if (PolledMotionController_RenderThread) if (PolledMotionController_RenderThread)
{ {
CurrentTrackingStatus = PolledMotionController_RenderThread->GetControllerTrackingStatus(PlayerIndex, MotionSource); EControllerHand HandType;
GetHandType(HandType);
FName GripSource = (HandType == EControllerHand::Left) ? FName("LeftGrip") : FName("RightGrip");
CurrentTrackingStatus = PolledMotionController_RenderThread->GetControllerTrackingStatus(PlayerIndex, GripSource);
if (PolledMotionController_RenderThread->GetControllerOrientationAndPosition(PlayerIndex, MotionSource, Orientation, Position, WorldToMetersScale)) if (PolledMotionController_RenderThread->GetControllerOrientationAndPosition(PlayerIndex, MotionSource, Orientation, Position, WorldToMetersScale))
{ {
if (HasTrackingParameters()) if (HasTrackingParameters())
@ -7636,6 +7759,10 @@ void UGripMotionControllerComponent::Server_NotifyHandledTransaction_Implementat
if(LocalTransactionBuffer[i].GripID == GripID) if(LocalTransactionBuffer[i].GripID == GripID)
LocalTransactionBuffer.RemoveAt(i); LocalTransactionBuffer.RemoveAt(i);
} }
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocalTransactionBuffer, this);
#endif
} }
bool UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Validate(const FBPActorGripInformation & newGrip) bool UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Validate(const FBPActorGripInformation & newGrip)
@ -7645,6 +7772,8 @@ bool UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Valida
void UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Implementation(const FBPActorGripInformation & newGrip) void UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Implementation(const FBPActorGripInformation & newGrip)
{ {
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (!newGrip.GrippedObject || newGrip.GripMovementReplicationSetting != EGripMovementReplicationSettings::ClientSide_Authoritive) if (!newGrip.GrippedObject || newGrip.GripMovementReplicationSetting != EGripMovementReplicationSettings::ClientSide_Authoritive)
{ {
Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, newGrip.GripID); Client_NotifyInvalidLocalGrip(newGrip.GrippedObject, newGrip.GripID);
@ -7765,6 +7894,7 @@ void UGripMotionControllerComponent::Server_NotifyLocalGripAddedOrChanged_Implem
} }
int32 NewIndex = LocallyGrippedObjects.Add(newGrip); int32 NewIndex = LocallyGrippedObjects.Add(newGrip);
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (NewIndex != INDEX_NONE && LocallyGrippedObjects.Num() > 0) if (NewIndex != INDEX_NONE && LocallyGrippedObjects.Num() > 0)
{ {
@ -7808,6 +7938,8 @@ bool UGripMotionControllerComponent::Server_NotifyLocalGripRemoved_Validate(uint
void UGripMotionControllerComponent::Server_NotifyLocalGripRemoved_Implementation(uint8 GripID, const FTransform_NetQuantize &TransformAtDrop, FVector_NetQuantize100 OptAngularVelocity, FVector_NetQuantize100 OptLinearVelocity) void UGripMotionControllerComponent::Server_NotifyLocalGripRemoved_Implementation(uint8 GripID, const FTransform_NetQuantize &TransformAtDrop, FVector_NetQuantize100 OptAngularVelocity, FVector_NetQuantize100 OptLinearVelocity)
{ {
DIRTY_LOCALLY_GRIPPED_OBJECTS();
FBPActorGripInformation FoundGrip; FBPActorGripInformation FoundGrip;
EBPVRResultSwitch Result; EBPVRResultSwitch Result;
GetGripByID(FoundGrip, GripID, Result); GetGripByID(FoundGrip, GripID, Result);
@ -7861,6 +7993,7 @@ void UGripMotionControllerComponent::Server_NotifySecondaryAttachmentChanged_Imp
uint8 GripID, uint8 GripID,
const FBPSecondaryGripInfo& SecondaryGripInfo) const FBPSecondaryGripInfo& SecondaryGripInfo)
{ {
DIRTY_LOCALLY_GRIPPED_OBJECTS();
FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GripID); FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GripID);
if (GripInfo != nullptr) if (GripInfo != nullptr)
@ -7887,6 +8020,7 @@ void UGripMotionControllerComponent::Server_NotifySecondaryAttachmentChanged_Ret
uint8 GripID, uint8 GripID,
const FBPSecondaryGripInfo& SecondaryGripInfo, const FTransform_NetQuantize & NewRelativeTransform) const FBPSecondaryGripInfo& SecondaryGripInfo, const FTransform_NetQuantize & NewRelativeTransform)
{ {
DIRTY_LOCALLY_GRIPPED_OBJECTS();
FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GripID); FBPActorGripInformation * GripInfo = LocallyGrippedObjects.FindByKey(GripID);
if (GripInfo != nullptr) if (GripInfo != nullptr)
@ -7987,8 +8121,9 @@ void FExpandedLateUpdateManager::Setup(const FTransform& ParentToWorld, UGripMot
//void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, const int32 FrameNumber, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform) //void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, const int32 FrameNumber, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform)
void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform) void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, const FTransform& OldRelativeTransform, const FTransform& NewRelativeTransform)
{ {
check(IsInRenderingThread()); FRHICommandListBase& RHICmdList = FRHICommandListImmediate::Get();
check(IsInRenderingThread());
if (!UpdateStates[LateUpdateRenderReadIndex].Primitives.Num() || UpdateStates[LateUpdateRenderReadIndex].bSkip) if (!UpdateStates[LateUpdateRenderReadIndex].Primitives.Num() || UpdateStates[LateUpdateRenderReadIndex].bSkip)
{ {
@ -8025,7 +8160,7 @@ void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, cons
} }
else if (CachedSceneInfo->Proxy) else if (CachedSceneInfo->Proxy)
{ {
CachedSceneInfo->Proxy->ApplyLateUpdateTransform(LateUpdateTransform); CachedSceneInfo->Proxy->ApplyLateUpdateTransform(RHICmdList, LateUpdateTransform);
PrimitivePair.Value = -1; // Set the cached index to -1 to indicate that this primitive was already processed PrimitivePair.Value = -1; // Set the cached index to -1 to indicate that this primitive was already processed
/*if (FrameNumber >= 0) /*if (FrameNumber >= 0)
{ {
@ -8045,7 +8180,7 @@ void FExpandedLateUpdateManager::Apply_RenderThread(FSceneInterface* Scene, cons
if (RetrievedSceneInfo->Proxy && PrimitiveIndex != nullptr && *PrimitiveIndex >= 0)*/ if (RetrievedSceneInfo->Proxy && PrimitiveIndex != nullptr && *PrimitiveIndex >= 0)*/
if (RetrievedSceneInfo->Proxy && UpdateStates[LateUpdateRenderReadIndex].Primitives.Contains(RetrievedSceneInfo) && UpdateStates[LateUpdateRenderReadIndex].Primitives[RetrievedSceneInfo] >= 0) if (RetrievedSceneInfo->Proxy && UpdateStates[LateUpdateRenderReadIndex].Primitives.Contains(RetrievedSceneInfo) && UpdateStates[LateUpdateRenderReadIndex].Primitives[RetrievedSceneInfo] >= 0)
{ {
RetrievedSceneInfo->Proxy->ApplyLateUpdateTransform(LateUpdateTransform); RetrievedSceneInfo->Proxy->ApplyLateUpdateTransform(RHICmdList, LateUpdateTransform);
/*if (FrameNumber >= 0) /*if (FrameNumber >= 0)
{ {
RetrievedSceneInfo->Proxy->SetPatchingFrameNumber(FrameNumber); RetrievedSceneInfo->Proxy->SetPatchingFrameNumber(FrameNumber);
@ -8264,7 +8399,7 @@ bool UGripMotionControllerComponent::GetIsComponentHeld(const UPrimitiveComponen
return (GrippedObjects.FindByKey(ComponentToCheck) || LocallyGrippedObjects.FindByKey(ComponentToCheck)); return (GrippedObjects.FindByKey(ComponentToCheck) || LocallyGrippedObjects.FindByKey(ComponentToCheck));
return false; //return false;
} }
bool UGripMotionControllerComponent::GetIsSecondaryAttachment(const USceneComponent * ComponentToCheck, FBPActorGripInformation & Grip) bool UGripMotionControllerComponent::GetIsSecondaryAttachment(const USceneComponent * ComponentToCheck, FBPActorGripInformation & Grip)
@ -8378,3 +8513,81 @@ bool UGripMotionControllerComponent::HasAuthority() const
return bHasAuthority; return bHasAuthority;
} }
void UGripMotionControllerComponent::CheckTransactionBuffer()
{
if (LocalTransactionBuffer.Num())
{
for (int i = LocalTransactionBuffer.Num() - 1; i >= 0; --i)
{
if (LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped && LocalTransactionBuffer[i].GripID != LocalTransactionBuffer[i].ValueCache.CachedGripID)
{
// There appears to be a bug with TArray replication where if you replace an index with another value of that
// Index, it doesn't fully re-init the object, this is a workaround to re-zero non replicated variables
// when that happens.
LocalTransactionBuffer[i].ClearNonReppingItems();
}
if (!LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped && LocalTransactionBuffer[i].GrippedObject->IsValidLowLevelFast())
{
LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped = true;
LocalTransactionBuffer[i].ValueCache.CachedGripID = LocalTransactionBuffer[i].GripID;
int32 Index = LocallyGrippedObjects.Add(LocalTransactionBuffer[i]);
DIRTY_LOCALLY_GRIPPED_OBJECTS();
if (Index != INDEX_NONE)
{
NotifyGrip(LocallyGrippedObjects[Index]);
}
Server_NotifyHandledTransaction(LocalTransactionBuffer[i].GripID);
}
}
}
}
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UGripMotionControllerComponent::SetSmoothReplicatedMotion(bool bNewSmoothReplicatedMotion)
{
bSmoothReplicatedMotion = bNewSmoothReplicatedMotion;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, bSmoothReplicatedMotion, this);
#endif
}
void UGripMotionControllerComponent::SetReplicateWithoutTracking(bool bNewReplicateWithoutTracking)
{
bReplicateWithoutTracking = bNewReplicateWithoutTracking;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, bReplicateWithoutTracking, this);
#endif
}
void UGripMotionControllerComponent::SetControllerNetUpdateRate(float NewControllerNetUpdateRate)
{
ControllerNetUpdateRate = NewControllerNetUpdateRate;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, ControllerNetUpdateRate, this);
#endif
}
void UGripMotionControllerComponent::DIRTY_GRIPPED_OBJECTS()
{
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, GrippedObjects, this);
#endif
}
void UGripMotionControllerComponent::DIRTY_LOCALLY_GRIPPED_OBJECTS()
{
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGripMotionControllerComponent, LocallyGrippedObjects, this);
#endif
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -46,6 +46,12 @@ UGS_Melee::UGS_Melee(const FObjectInitializer& ObjectInitializer) :
bOnlyPenetrateWithTwoHands = false; bOnlyPenetrateWithTwoHands = false;
} }
void UGS_Melee::SetIsLodged(bool IsLodged, UPrimitiveComponent* LodgeComponent)
{
bIsLodged = IsLodged;
LodgedComponent = LodgeComponent;
}
void UGS_Melee::UpdateDualHandInfo() void UGS_Melee::UpdateDualHandInfo()
{ {
TArray<FBPGripPair> HoldingControllers; TArray<FBPGripPair> HoldingControllers;
@ -448,12 +454,6 @@ void UGS_Melee::OnGripRelease_Implementation(UGripMotionControllerComponent* Rel
TArray<FBPGripPair> HoldingControllers; TArray<FBPGripPair> HoldingControllers;
IVRGripInterface::Execute_IsHeld(GetParent(), HoldingControllers, bIsHeld); IVRGripInterface::Execute_IsHeld(GetParent(), HoldingControllers, bIsHeld);
//if(!bAlwaysTickPenetration)
//SetTickEnabled(false);
//if (!bAlwaysTickPenetration)
// bCheckLodge = false;
if (SecondaryHand.IsValid() && SecondaryHand.HoldingController == ReleasingController && SecondaryHand.GripID == GripInformation.GripID) if (SecondaryHand.IsValid() && SecondaryHand.HoldingController == ReleasingController && SecondaryHand.GripID == GripInformation.GripID)
{ {
SecondaryHand = FBPGripPair(); SecondaryHand = FBPGripPair();
@ -471,6 +471,37 @@ void UGS_Melee::OnGripRelease_Implementation(UGripMotionControllerComponent* Rel
} }
} }
if (COMType != EVRMeleeComType::VRPMELEECOM_Normal)
{
if (UPrimitiveComponent* PrimComp = Cast<UPrimitiveComponent>(GetParentSceneComp()))
{
if (FBodyInstance* rBodyInstance = PrimComp->GetBodyInstance())
{
if (rBodyInstance->IsValidBodyInstance() && rBodyInstance->BodySetup.IsValid())
{
// If bound we need to cancel out
bool bWasBound = false;
if (PrimaryHand.IsValid())
{
if (rBodyInstance->OnRecalculatedMassProperties().IsBoundToObject(PrimaryHand.HoldingController))
{
rBodyInstance->OnRecalculatedMassProperties().RemoveAll(this);
bWasBound = true;
}
}
rBodyInstance->UpdateMassProperties();
// Restore binding
if (bWasBound)
{
rBodyInstance->OnRecalculatedMassProperties().AddUObject(PrimaryHand.HoldingController, &UGripMotionControllerComponent::OnGripMassUpdated);
}
}
}
}
}
if (PrimaryHand.IsValid()) if (PrimaryHand.IsValid())
{ {
@ -480,6 +511,13 @@ void UGS_Melee::OnGripRelease_Implementation(UGripMotionControllerComponent* Rel
{ {
FBPActorGripInformation * GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID); FBPActorGripInformation * GripInfo = PrimaryHand.HoldingController->GetGripPtrByID(PrimaryHand.GripID);
// Reset custom COM changes
if (!SecondaryHand.IsValid())
{
HandleInfo->bSkipResettingCom = false;
UpdateDualHandInfo();
}
if (GripInfo) if (GripInfo)
{ {
//Reset defaults here still!!! //Reset defaults here still!!!
@ -760,8 +798,8 @@ void UGS_Melee::HandlePostPhysicsHandle(UGripMotionControllerComponent* Gripping
PrimaryHandPhysicsSettings.FillTo(HandleInfo); PrimaryHandPhysicsSettings.FillTo(HandleInfo);
} }
//HandleInfo->bSetCOM = false; // Should i remove this? if (COMType != EVRMeleeComType::VRPMELEECOM_Normal)
HandleInfo->bSkipResettingCom = false; SetComBetweenHands(GrippingController, HandleInfo);
} }
} }
@ -793,6 +831,10 @@ void UGS_Melee::SetComBetweenHands(UGripMotionControllerComponent* GrippingContr
HandleInfo->bSetCOM = true; // Should i remove this? HandleInfo->bSetCOM = true; // Should i remove this?
HandleInfo->bSkipResettingCom = true; HandleInfo->bSkipResettingCom = true;
} }
else
{
HandleInfo->bSkipResettingCom = false;
}
} }
/*void UGS_Melee::Tick(float DeltaTime) /*void UGS_Melee::Tick(float DeltaTime)

View file

@ -19,7 +19,6 @@
#include "Net/Core/PushModel/PushModel.h" #include "Net/Core/PushModel/PushModel.h"
#endif #endif
//============================================================================= //=============================================================================
AGrippableActor::AGrippableActor(const FObjectInitializer& ObjectInitializer) AGrippableActor::AGrippableActor(const FObjectInitializer& ObjectInitializer)
: Super() : Super()
@ -62,13 +61,20 @@ void AGrippableActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(AGrippableActor, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(AGrippableActor, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(AGrippableActor, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(AGrippableActor, bAllowIgnoringAttachOnOwner); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME(AGrippableActor, ClientAuthReplicationData); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(AGrippableActor, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, bAllowIgnoringAttachOnOwner, PushModelParams);
DOREPLIFETIME_CONDITION(AGrippableActor, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, ClientAuthReplicationData, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableActor, GameplayTags, PushModelParamsWithCondition);
DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
@ -78,7 +84,6 @@ void AGrippableActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty
void AGrippableActor::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void AGrippableActor::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
{ {
// Don't replicate if set to not do it // Don't replicate if set to not do it
DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags); DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, VRGripInterfaceSettings, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, GameplayTags, bRepGripSettingsAndGameplayTags); DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(AGrippableActor, GameplayTags, bRepGripSettingsAndGameplayTags);
@ -254,6 +259,30 @@ void AGrippableActor::GatherCurrentMovement()
} }
} }
bool AGrippableActor::ShouldWeSkipAttachmentReplication(bool bConsiderHeld) const
{
if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client)
return false;
if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive ||
VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep)
{
// First return if we are locally held (owner may not have replicated yet)
for (const FBPGripPair& Grip : VRGripInterfaceSettings.HoldingControllers)
{
if (IsValid(Grip.HoldingController) && Grip.HoldingController->IsLocallyControlled())
{
return true;
}
}
// then return if we have a local net owner
return HasLocalNetOwner();
}
else
return false;
}
void AGrippableActor::OnRep_AttachmentReplication() void AGrippableActor::OnRep_AttachmentReplication()
{ {
if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication()))
@ -823,3 +852,79 @@ void AGrippableActor::GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>
} }
} }
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void AGrippableActor::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& AGrippableActor::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void AGrippableActor::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, bRepGripSettingsAndGameplayTags, this);
#endif
}
void AGrippableActor::SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner)
{
bAllowIgnoringAttachOnOwner = bNewAllowIgnoringAttachOnOwner;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, bAllowIgnoringAttachOnOwner, this);
#endif
}
FVRClientAuthReplicationData& AGrippableActor::GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData)
{
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, ClientAuthReplicationData, this);
#endif
return ClientAuthReplicationData;
}
FBPInterfaceProperties& AGrippableActor::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& AGrippableActor::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableActor, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -8,6 +8,10 @@
#include "GripScripts/VRGripScriptBase.h" #include "GripScripts/VRGripScriptBase.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UGrippableBoxComponent::~UGrippableBoxComponent() UGrippableBoxComponent::~UGrippableBoxComponent()
{ {
@ -47,12 +51,19 @@ void UGrippableBoxComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeP
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UGrippableBoxComponent, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(UGrippableBoxComponent, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UGrippableBoxComponent, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(UGrippableBoxComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableBoxComponent, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableBoxComponent, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableBoxComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UGrippableBoxComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UGrippableBoxComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -321,3 +332,71 @@ void UGrippableBoxComponent::OnComponentDestroyed(bool bDestroyingHierarchy)
GripLogicScripts.Empty(); GripLogicScripts.Empty();
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UGrippableBoxComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& UGrippableBoxComponent::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void UGrippableBoxComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, bRepGripSettingsAndGameplayTags, this);
#endif
}
void UGrippableBoxComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, bReplicateMovement, this);
#endif
}
FBPInterfaceProperties& UGrippableBoxComponent::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& UGrippableBoxComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableBoxComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -8,6 +8,10 @@
#include "GripScripts/VRGripScriptBase.h" #include "GripScripts/VRGripScriptBase.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UGrippableCapsuleComponent::UGrippableCapsuleComponent(const FObjectInitializer& ObjectInitializer) UGrippableCapsuleComponent::UGrippableCapsuleComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -43,12 +47,19 @@ void UGrippableCapsuleComponent::GetLifetimeReplicatedProps(TArray< class FLifet
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UGrippableCapsuleComponent, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(UGrippableCapsuleComponent, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UGrippableCapsuleComponent, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(UGrippableCapsuleComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableCapsuleComponent, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableCapsuleComponent, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableCapsuleComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UGrippableCapsuleComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UGrippableCapsuleComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -321,3 +332,71 @@ void UGrippableCapsuleComponent::OnComponentDestroyed(bool bDestroyingHierarchy)
GripLogicScripts.Empty(); GripLogicScripts.Empty();
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UGrippableCapsuleComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& UGrippableCapsuleComponent::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void UGrippableCapsuleComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, bRepGripSettingsAndGameplayTags, this);
#endif
}
void UGrippableCapsuleComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, bReplicateMovement, this);
#endif
}
FBPInterfaceProperties& UGrippableCapsuleComponent::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& UGrippableCapsuleComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableCapsuleComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -37,7 +37,18 @@ void UOptionalRepSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UOptionalRepSkeletalMeshComponent, bReplicateMovement); // For std properties
FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UOptionalRepSkeletalMeshComponent, bReplicateMovement, PushModelParams);
}
void UOptionalRepSkeletalMeshComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UOptionalRepSkeletalMeshComponent, bReplicateMovement, this);
#endif
} }
void UOptionalRepSkeletalMeshComponent::GetWeldedBodies(TArray<FBodyInstance*>& OutWeldedBodies, TArray<FName>& OutLabels, bool bIncludingAutoWeld) void UOptionalRepSkeletalMeshComponent::GetWeldedBodies(TArray<FBodyInstance*>& OutWeldedBodies, TArray<FName>& OutLabels, bool bIncludingAutoWeld)
@ -152,13 +163,20 @@ void AGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLife
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(AGrippableSkeletalMeshActor, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(AGrippableSkeletalMeshActor, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(AGrippableSkeletalMeshActor, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(AGrippableSkeletalMeshActor, bAllowIgnoringAttachOnOwner); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME(AGrippableSkeletalMeshActor, ClientAuthReplicationData); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, bAllowIgnoringAttachOnOwner, PushModelParams);
DOREPLIFETIME_CONDITION(AGrippableSkeletalMeshActor, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, ClientAuthReplicationData, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, GameplayTags, PushModelParamsWithCondition);
DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
@ -732,6 +750,30 @@ void AGrippableSkeletalMeshActor::Server_GetClientAuthReplication_Implementation
} }
} }
bool AGrippableSkeletalMeshActor::ShouldWeSkipAttachmentReplication(bool bConsiderHeld) const
{
if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client)
return false;
if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive ||
VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep)
{
// First return if we are locally held (owner may not have replicated yet)
for (const FBPGripPair& Grip : VRGripInterfaceSettings.HoldingControllers)
{
if (IsValid(Grip.HoldingController) && Grip.HoldingController->IsLocallyControlled())
{
return true;
}
}
// then return if we have a local net owner
return HasLocalNetOwner();
}
else
return false;
}
void AGrippableSkeletalMeshActor::OnRep_AttachmentReplication() void AGrippableSkeletalMeshActor::OnRep_AttachmentReplication()
{ {
if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication()))
@ -908,3 +950,79 @@ void AGrippableSkeletalMeshActor::GetSubobjectsWithStableNamesForNetworking(TArr
} }
} }
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void AGrippableSkeletalMeshActor::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& AGrippableSkeletalMeshActor::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void AGrippableSkeletalMeshActor::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, bRepGripSettingsAndGameplayTags, this);
#endif
}
void AGrippableSkeletalMeshActor::SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner)
{
bAllowIgnoringAttachOnOwner = bNewAllowIgnoringAttachOnOwner;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, bAllowIgnoringAttachOnOwner, this);
#endif
}
FVRClientAuthReplicationData& AGrippableSkeletalMeshActor::GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData)
{
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, ClientAuthReplicationData, this);
#endif
return ClientAuthReplicationData;
}
FBPInterfaceProperties& AGrippableSkeletalMeshActor::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& AGrippableSkeletalMeshActor::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -8,6 +8,9 @@
#include "GripScripts/VRGripScriptBase.h" #include "GripScripts/VRGripScriptBase.h"
#include "PhysicsEngine/PhysicsAsset.h" // Tmp until epic bug fixes skeletal welding #include "PhysicsEngine/PhysicsAsset.h" // Tmp until epic bug fixes skeletal welding
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UGrippableSkeletalMeshComponent::UGrippableSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer) UGrippableSkeletalMeshComponent::UGrippableSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer)
@ -44,12 +47,19 @@ void UGrippableSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class F
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UGrippableSkeletalMeshComponent, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(UGrippableSkeletalMeshComponent, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UGrippableSkeletalMeshComponent, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(UGrippableSkeletalMeshComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableSkeletalMeshComponent, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableSkeletalMeshComponent, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSkeletalMeshComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UGrippableSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UGrippableSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -390,3 +400,71 @@ FBodyInstance* UGrippableSkeletalMeshComponent::GetBodyInstance(FName BoneName,
return BodyInst; return BodyInst;
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UGrippableSkeletalMeshComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& UGrippableSkeletalMeshComponent::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void UGrippableSkeletalMeshComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, bRepGripSettingsAndGameplayTags, this);
#endif
}
void UGrippableSkeletalMeshComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, bReplicateMovement, this);
#endif
}
FBPInterfaceProperties& UGrippableSkeletalMeshComponent::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& UGrippableSkeletalMeshComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSkeletalMeshComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -8,6 +8,11 @@
#include "GripScripts/VRGripScriptBase.h" #include "GripScripts/VRGripScriptBase.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UGrippableSphereComponent::UGrippableSphereComponent(const FObjectInitializer& ObjectInitializer) UGrippableSphereComponent::UGrippableSphereComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -42,12 +47,19 @@ void UGrippableSphereComponent::GetLifetimeReplicatedProps(TArray< class FLifeti
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UGrippableSphereComponent, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(UGrippableSphereComponent, bReplicateGripScripts) FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UGrippableSphereComponent, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(UGrippableSphereComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableSphereComponent, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableSphereComponent, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableSphereComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UGrippableSphereComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UGrippableSphereComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -320,3 +332,72 @@ void UGrippableSphereComponent::OnComponentDestroyed(bool bDestroyingHierarchy)
GripLogicScripts.Empty(); GripLogicScripts.Empty();
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UGrippableSphereComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& UGrippableSphereComponent::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void UGrippableSphereComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, bRepGripSettingsAndGameplayTags, this);
#endif
}
void UGrippableSphereComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, bReplicateMovement, this);
#endif
}
FBPInterfaceProperties& UGrippableSphereComponent::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& UGrippableSphereComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableSphereComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -110,13 +110,20 @@ void AGrippableStaticMeshActor::GetLifetimeReplicatedProps(TArray< class FLifeti
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(AGrippableStaticMeshActor, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(AGrippableStaticMeshActor, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(AGrippableStaticMeshActor, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(AGrippableStaticMeshActor, bAllowIgnoringAttachOnOwner); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME(AGrippableStaticMeshActor, ClientAuthReplicationData); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(AGrippableStaticMeshActor, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, bAllowIgnoringAttachOnOwner, PushModelParams);
DOREPLIFETIME_CONDITION(AGrippableStaticMeshActor, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, ClientAuthReplicationData, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableStaticMeshActor, GameplayTags, PushModelParamsWithCondition);
DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
@ -682,6 +689,30 @@ void AGrippableStaticMeshActor::Server_GetClientAuthReplication_Implementation(c
} }
} }
bool AGrippableStaticMeshActor::ShouldWeSkipAttachmentReplication(bool bConsiderHeld) const
{
if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client)
return false;
if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive ||
VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep)
{
// First return if we are locally held (owner may not have replicated yet)
for (const FBPGripPair& Grip : VRGripInterfaceSettings.HoldingControllers)
{
if (IsValid(Grip.HoldingController) && Grip.HoldingController->IsLocallyControlled())
{
return true;
}
}
// then return if we have a local net owner
return HasLocalNetOwner();
}
else
return false;
}
void AGrippableStaticMeshActor::OnRep_AttachmentReplication() void AGrippableStaticMeshActor::OnRep_AttachmentReplication()
{ {
if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication())) if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication()))
@ -774,6 +805,12 @@ void AGrippableStaticMeshActor::OnRep_ReplicatedMovement()
return; return;
} }
if (VRGripInterfaceSettings.HoldingControllers.Num() > 0)
{
ShouldWeSkipAttachmentReplication();
int gg = 0;
}
Super::OnRep_ReplicatedMovement(); Super::OnRep_ReplicatedMovement();
} }
@ -859,3 +896,79 @@ void AGrippableStaticMeshActor::GetSubobjectsWithStableNamesForNetworking(TArray
} }
} }
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void AGrippableStaticMeshActor::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& AGrippableStaticMeshActor::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void AGrippableStaticMeshActor::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, bRepGripSettingsAndGameplayTags, this);
#endif
}
void AGrippableStaticMeshActor::SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner)
{
bAllowIgnoringAttachOnOwner = bNewAllowIgnoringAttachOnOwner;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, bAllowIgnoringAttachOnOwner, this);
#endif
}
FVRClientAuthReplicationData& AGrippableStaticMeshActor::GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData)
{
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, ClientAuthReplicationData, this);
#endif
return ClientAuthReplicationData;
}
FBPInterfaceProperties& AGrippableStaticMeshActor::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& AGrippableStaticMeshActor::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableStaticMeshActor, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -7,6 +7,9 @@
#include "VRExpansionFunctionLibrary.h" #include "VRExpansionFunctionLibrary.h"
#include "GripScripts/VRGripScriptBase.h" #include "GripScripts/VRGripScriptBase.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UGrippableStaticMeshComponent::UGrippableStaticMeshComponent(const FObjectInitializer& ObjectInitializer) UGrippableStaticMeshComponent::UGrippableStaticMeshComponent(const FObjectInitializer& ObjectInitializer)
@ -43,12 +46,19 @@ void UGrippableStaticMeshComponent::GetLifetimeReplicatedProps(TArray< class FLi
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(UGrippableStaticMeshComponent, GripLogicScripts, COND_Custom); // For std properties
DOREPLIFETIME(UGrippableStaticMeshComponent, bReplicateGripScripts); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UGrippableStaticMeshComponent, bRepGripSettingsAndGameplayTags);
DOREPLIFETIME(UGrippableStaticMeshComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, bReplicateGripScripts, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableStaticMeshComponent, VRGripInterfaceSettings, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, bRepGripSettingsAndGameplayTags, PushModelParams);
DOREPLIFETIME_CONDITION(UGrippableStaticMeshComponent, GameplayTags, COND_Custom); DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, GripLogicScripts, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, VRGripInterfaceSettings, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(UGrippableStaticMeshComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UGrippableStaticMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UGrippableStaticMeshComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -315,3 +325,71 @@ void UGrippableStaticMeshComponent::OnComponentDestroyed(bool bDestroyingHierarc
GripLogicScripts.Empty(); GripLogicScripts.Empty();
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UGrippableStaticMeshComponent::SetReplicateGripScripts(bool bNewReplicateGripScripts)
{
bReplicateGripScripts = bNewReplicateGripScripts;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, bReplicateGripScripts, this);
#endif
}
TArray<TObjectPtr<UVRGripScriptBase>>& UGrippableStaticMeshComponent::GetGripLogicScripts()
{
#if WITH_PUSH_MODEL
if (bReplicateGripScripts)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, GripLogicScripts, this);
}
#endif
return GripLogicScripts;
}
void UGrippableStaticMeshComponent::SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags)
{
bRepGripSettingsAndGameplayTags = bNewRepGripSettingsAndGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, bRepGripSettingsAndGameplayTags, this);
#endif
}
void UGrippableStaticMeshComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, bReplicateMovement, this);
#endif
}
FBPInterfaceProperties& UGrippableStaticMeshComponent::GetVRGripInterfaceSettings(bool bMarkDirty)
{
#if WITH_PUSH_MODEL
if (bMarkDirty && bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, VRGripInterfaceSettings, this);
}
#endif
return VRGripInterfaceSettings;
}
FGameplayTagContainer& UGrippableStaticMeshComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGripSettingsAndGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UGrippableStaticMeshComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////

View file

@ -3,11 +3,16 @@
#include "Grippables/HandSocketComponent.h" #include "Grippables/HandSocketComponent.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(HandSocketComponent) #include UE_INLINE_GENERATED_CPP_BY_NAME(HandSocketComponent)
#include "CoreMinimal.h"
#include "UObject/UObjectIterator.h"
#include "Engine/CollisionProfile.h" #include "Engine/CollisionProfile.h"
#include "BoneContainer.h"
#include "Animation/AnimSequence.h" #include "Animation/AnimSequence.h"
#include "Animation/AnimInstanceProxy.h" #include "Animation/AnimInstanceProxy.h"
#include "Animation/PoseSnapshot.h" #include "Animation/PoseSnapshot.h"
#include "Animation/AnimData/AnimDataModel.h" #include "Animation/AnimData/AnimDataModel.h"
#include "Engine/SkinnedAssetCommon.h"
#include "Engine/SkinnedAsset.h"
//#include "VRExpansionFunctionLibrary.h" //#include "VRExpansionFunctionLibrary.h"
#include "Components/SkeletalMeshComponent.h" #include "Components/SkeletalMeshComponent.h"
#include "Components/PoseableMeshComponent.h" #include "Components/PoseableMeshComponent.h"
@ -17,6 +22,10 @@
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "Serialization/CustomVersion.h" #include "Serialization/CustomVersion.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
DEFINE_LOG_CATEGORY(LogVRHandSocketComponent); DEFINE_LOG_CATEGORY(LogVRHandSocketComponent);
const FGuid FVRHandSocketCustomVersion::GUID(0x5A018B7F, 0x48A7AFDE, 0xAFBEB580, 0xAD575412); const FGuid FVRHandSocketCustomVersion::GUID(0x5A018B7F, 0x48A7AFDE, 0xAFBEB580, 0xAD575412);
@ -877,9 +886,16 @@ void UHandSocketComponent::GetLifetimeReplicatedProps(TArray< class FLifetimePro
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UHandSocketComponent, bRepGameplayTags); // For std properties
DOREPLIFETIME(UHandSocketComponent, bReplicateMovement); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_CONDITION(UHandSocketComponent, GameplayTags, COND_Custom);
DOREPLIFETIME_WITH_PARAMS_FAST(UHandSocketComponent, bRepGameplayTags, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UHandSocketComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UHandSocketComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UHandSocketComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UHandSocketComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -964,3 +980,46 @@ UHandSocketComponent* UHandSocketComponent::GetHandSocketComponentFromObject(UOb
return nullptr; return nullptr;
} }
/////////////////////////////////////////////////
//- Push networking getter / setter functions
/////////////////////////////////////////////////
void UHandSocketComponent::SetRepGameplayTags(bool bNewRepGameplayTags)
{
bRepGameplayTags = bNewRepGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UHandSocketComponent, bRepGameplayTags, this);
#endif
}
void UHandSocketComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UHandSocketComponent, bReplicateMovement, this);
#endif
}
FGameplayTagContainer& UHandSocketComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UHandSocketComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}
/////////////////////////////////////////////////
//- End Push networking getter / setter functions
/////////////////////////////////////////////////
void UHandSocketAnimInstance::NativeInitializeAnimation()
{
Super::NativeInitializeAnimation();
OwningSocket = Cast<UHandSocketComponent>(GetOwningComponent()->GetAttachParent());
}

View file

@ -9,6 +9,10 @@
#include "GameFramework/Character.h" #include "GameFramework/Character.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UVRButtonComponent::UVRButtonComponent(const FObjectInitializer& ObjectInitializer) UVRButtonComponent::UVRButtonComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -48,10 +52,17 @@ void UVRButtonComponent::GetLifetimeReplicatedProps(TArray< class FLifetimePrope
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UVRButtonComponent, InitialRelativeTransform); // For std properties
DOREPLIFETIME(UVRButtonComponent, bReplicateMovement); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UVRButtonComponent, StateChangeAuthorityType);
DOREPLIFETIME_CONDITION(UVRButtonComponent, bButtonState, COND_InitialOnly); DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, InitialRelativeTransform, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, bReplicateMovement, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, StateChangeAuthorityType, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_InitialOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UVRButtonComponent, bButtonState, PushModelParamsWithCondition);
} }
void UVRButtonComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UVRButtonComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -423,3 +434,27 @@ FVector UVRButtonComponent::SetAxisValue(float SetValue)
return vec; return vec;
} }
void UVRButtonComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRButtonComponent, bReplicateMovement, this);
#endif
}
void UVRButtonComponent::SetStateChangeAuthorityType(EVRStateChangeAuthorityType NewStateChangeAuthorityType)
{
StateChangeAuthorityType = NewStateChangeAuthorityType;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRButtonComponent, StateChangeAuthorityType, this);
#endif
}
void UVRButtonComponent::SetButtonState(bool bNewButtonState)
{
bButtonState = bNewButtonState;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRButtonComponent, bButtonState, this);
#endif
}

View file

@ -7,6 +7,10 @@
#include "GripMotionControllerComponent.h" #include "GripMotionControllerComponent.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UVRDialComponent::UVRDialComponent(const FObjectInitializer& ObjectInitializer) UVRDialComponent::UVRDialComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -63,12 +67,19 @@ void UVRDialComponent::GetLifetimeReplicatedProps(TArray< class FLifetimePropert
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UVRDialComponent, InitialRelativeTransform); // For std properties
FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, InitialRelativeTransform, PushModelParams);
//DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly); //DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly);
DOREPLIFETIME(UVRDialComponent, bRepGameplayTags); DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, bRepGameplayTags, PushModelParams);
DOREPLIFETIME(UVRDialComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, bReplicateMovement, PushModelParams);
DOREPLIFETIME_CONDITION(UVRDialComponent, GameplayTags, COND_Custom);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UVRDialComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UVRDialComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UVRDialComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -255,10 +266,20 @@ void UVRDialComponent::OnGripRelease_Implementation(UGripMotionControllerCompone
} }
} }
} }
else if (bDialUsesAngleSnap && SnapAngleIncrement > 0.f && FMath::Abs(FMath::Fmod(CurRotBackEnd, SnapAngleIncrement)) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) else if (bDialUsesAngleSnap && SnapAngleIncrement > 0.f)// && FMath::Abs(FMath::Fmod(CurRotBackEnd, SnapAngleIncrement)) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold))
{
float AngleOffsetCheck = FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - FRotator::ClampAxis(LastSnapAngle));
float TargetSnap = FMath::RoundToFloat(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement));
if (FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - TargetSnap) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold))
{
if (AngleOffsetCheck >= SnapAngleThreshold)//FMath::Min(SnapAngleIncrement, SnapAngleThreshold))
{ {
this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator());
CurRotBackEnd = FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement); CurRotBackEnd = FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement);
}
}
if (bUseRollover) if (bUseRollover)
{ {
@ -556,7 +577,14 @@ void UVRDialComponent::AddDialAngle(float DialAngleDelta, bool bCallEvents, bool
LastSnapAngle = CurrentDialAngle; LastSnapAngle = CurrentDialAngle;
} }
} }
else if (bDialUsesAngleSnap && SnapAngleIncrement > 0.f && FMath::Abs(FMath::Fmod(CurRotBackEnd, SnapAngleIncrement)) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold)) else if (bDialUsesAngleSnap && SnapAngleIncrement > 0.f)// && FMath::Abs(FMath::Fmod(CurRotBackEnd, SnapAngleIncrement)) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold))
{
float AngleOffsetCheck = FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - FRotator::ClampAxis(LastSnapAngle));
float TargetSnap = FMath::RoundToFloat(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement));
if (FMath::Abs(FRotator::ClampAxis(CurRotBackEnd) - TargetSnap) <= FMath::Min(SnapAngleIncrement, SnapAngleThreshold))
{
if (AngleOffsetCheck >= SnapAngleThreshold)//FMath::Min(SnapAngleIncrement, SnapAngleThreshold))
{ {
if (!bSkipSettingRot) if (!bSkipSettingRot)
this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement)), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator()); this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(FMath::GridSnap(CurRotBackEnd, SnapAngleIncrement)), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator());
@ -570,6 +598,14 @@ void UVRDialComponent::AddDialAngle(float DialAngleDelta, bool bCallEvents, bool
LastSnapAngle = CurrentDialAngle; LastSnapAngle = CurrentDialAngle;
} }
}
else
{
if (!bSkipSettingRot)
this->SetRelativeRotation((FTransform(UVRInteractibleFunctionLibrary::SetAxisValueRot(DialRotationAxis, FMath::UnwindDegrees(CurRotBackEnd), FRotator::ZeroRotator)) * InitialRelativeTransform).Rotator());
CurrentDialAngle = FMath::RoundToFloat(CurRotBackEnd);
}
}
else else
{ {
if (!bSkipSettingRot) if (!bSkipSettingRot)
@ -583,6 +619,11 @@ void UVRDialComponent::ResetInitialDialLocation()
{ {
// Get our initial relative transform to our parent (or not if un-parented). // Get our initial relative transform to our parent (or not if un-parented).
InitialRelativeTransform = this->GetRelativeTransform(); InitialRelativeTransform = this->GetRelativeTransform();
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, InitialRelativeTransform, this);
#endif
CurRotBackEnd = 0.0f; CurRotBackEnd = 0.0f;
CalculateDialProgress(); CalculateDialProgress();
} }
@ -594,3 +635,32 @@ void UVRDialComponent::CalculateDialProgress()
CurRotBackEnd = LastGripRot; CurRotBackEnd = LastGripRot;
AddDialAngle(0.0f, false, true); AddDialAngle(0.0f, false, true);
} }
void UVRDialComponent::SetRepGameplayTags(bool bNewRepGameplayTags)
{
bRepGameplayTags = bNewRepGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, bRepGameplayTags, this);
#endif
}
void UVRDialComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, bReplicateMovement, this);
#endif
}
FGameplayTagContainer& UVRDialComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UVRDialComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}

View file

@ -7,6 +7,10 @@
#include "VRExpansionFunctionLibrary.h" #include "VRExpansionFunctionLibrary.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UVRLeverComponent::UVRLeverComponent(const FObjectInitializer& ObjectInitializer) UVRLeverComponent::UVRLeverComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -85,12 +89,19 @@ void UVRLeverComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProper
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UVRLeverComponent, InitialRelativeTransform); // For std properties
//DOREPLIFETIME_CONDITION(UVRLeverComponent, bIsLerping, COND_InitialOnly); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(UVRLeverComponent, bRepGameplayTags); DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, InitialRelativeTransform, PushModelParams);
DOREPLIFETIME(UVRLeverComponent, bReplicateMovement); //DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly);
DOREPLIFETIME_CONDITION(UVRLeverComponent, GameplayTags, COND_Custom);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, bRepGameplayTags, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UVRLeverComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UVRLeverComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UVRLeverComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -655,6 +666,11 @@ void UVRLeverComponent::ResetInitialLeverLocation(bool bAllowThrowingEvents)
{ {
// Get our initial relative transform to our parent (or not if un-parented). // Get our initial relative transform to our parent (or not if un-parented).
InitialRelativeTransform = this->GetRelativeTransform(); InitialRelativeTransform = this->GetRelativeTransform();
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, InitialRelativeTransform, this);
#endif
CalculateCurrentAngle(InitialRelativeTransform); CalculateCurrentAngle(InitialRelativeTransform);
ProccessCurrentState(bIsLerping, bAllowThrowingEvents, bAllowThrowingEvents); ProccessCurrentState(bIsLerping, bAllowThrowingEvents, bAllowThrowingEvents);
} }
@ -817,3 +833,31 @@ float UVRLeverComponent::CalcAngle(EVRInteractibleLeverAxis AxisToCalc, FVector
bIsInFirstTick = false; bIsInFirstTick = false;
return ReturnAxis; return ReturnAxis;
} }
void UVRLeverComponent::SetRepGameplayTags(bool bNewRepGameplayTags)
{
bRepGameplayTags = bNewRepGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, bRepGameplayTags, this);
#endif
}
void UVRLeverComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, bReplicateMovement, this);
#endif
}
FGameplayTagContainer& UVRLeverComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UVRLeverComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}

View file

@ -9,6 +9,10 @@
//#include "PhysicsEngine/ConstraintInstance.h" //#include "PhysicsEngine/ConstraintInstance.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UVRMountComponent::UVRMountComponent(const FObjectInitializer& ObjectInitializer) UVRMountComponent::UVRMountComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -58,9 +62,16 @@ void UVRMountComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProper
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UVRMountComponent, bRepGameplayTags); // For std properties
DOREPLIFETIME(UVRMountComponent, bReplicateMovement); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_CONDITION(UVRMountComponent, GameplayTags, COND_Custom);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRMountComponent, bRepGameplayTags, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRMountComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UVRMountComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UVRMountComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UVRMountComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -577,8 +588,42 @@ void UVRMountComponent::SetHeld_Implementation(UGripMotionControllerComponent *
return FBPInteractionSettings(); return FBPInteractionSettings();
}*/ }*/
void UVRMountComponent::ResetInitialMountLocation()
{
// Get our initial relative transform to our parent (or not if un-parented).
InitialRelativeTransform = this->GetRelativeTransform();
}
bool UVRMountComponent::GetGripScripts_Implementation(TArray<UVRGripScriptBase*> & ArrayReference) bool UVRMountComponent::GetGripScripts_Implementation(TArray<UVRGripScriptBase*> & ArrayReference)
{ {
return false; return false;
} }
void UVRMountComponent::SetRepGameplayTags(bool bNewRepGameplayTags)
{
bRepGameplayTags = bNewRepGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRMountComponent, bRepGameplayTags, this);
#endif
}
void UVRMountComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRMountComponent, bReplicateMovement, this);
#endif
}
FGameplayTagContainer& UVRMountComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UVRMountComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}

View file

@ -8,6 +8,10 @@
#include "GripMotionControllerComponent.h" #include "GripMotionControllerComponent.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
//============================================================================= //=============================================================================
UVRSliderComponent::UVRSliderComponent(const FObjectInitializer& ObjectInitializer) UVRSliderComponent::UVRSliderComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -84,13 +88,20 @@ void UVRSliderComponent::GetLifetimeReplicatedProps(TArray< class FLifetimePrope
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UVRSliderComponent, InitialRelativeTransform); // For std properties
DOREPLIFETIME(UVRSliderComponent, SplineComponentToFollow); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
//DOREPLIFETIME_CONDITION(UVRSliderComponent, bIsLerping, COND_InitialOnly);
DOREPLIFETIME(UVRSliderComponent, bRepGameplayTags); DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, InitialRelativeTransform, PushModelParams);
DOREPLIFETIME(UVRSliderComponent, bReplicateMovement); DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, SplineComponentToFollow, PushModelParams);
DOREPLIFETIME_CONDITION(UVRSliderComponent, GameplayTags, COND_Custom); //DOREPLIFETIME_CONDITION(UVRDialComponent, bIsLerping, COND_InitialOnly);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, bRepGameplayTags, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, bReplicateMovement, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_Custom, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UVRSliderComponent, GameplayTags, PushModelParamsWithCondition);
} }
void UVRSliderComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void UVRSliderComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -734,7 +745,12 @@ FVector UVRSliderComponent::ClampSlideVector(FVector ValueToClamp)
FVector MinScale = (bUseLegacyLogic ? MinSlideDistance : MinSlideDistance.GetAbs()) * fScaleFactor; FVector MinScale = (bUseLegacyLogic ? MinSlideDistance : MinSlideDistance.GetAbs()) * fScaleFactor;
FVector Dist = (bUseLegacyLogic ? (MinSlideDistance + MaxSlideDistance) : (MinSlideDistance.GetAbs() + MaxSlideDistance.GetAbs())) * fScaleFactor; FVector Dist = (bUseLegacyLogic ? (MinSlideDistance + MaxSlideDistance) : (MinSlideDistance.GetAbs() + MaxSlideDistance.GetAbs())) * fScaleFactor;
FVector Progress = (ValueToClamp - (-MinScale)) / Dist; FVector Progress{
Dist.X > 0.0f ? (ValueToClamp.X - (-MinScale.X)) / Dist.X : 0.f,
Dist.Y > 0.0f ? (ValueToClamp.Y - (-MinScale.Y)) / Dist.Y : 0.f,
Dist.Z > 0.0f ? (ValueToClamp.Z - (-MinScale.Z)) / Dist.Z : 0.f,
};
if (bSliderUsesSnapPoints) if (bSliderUsesSnapPoints)
{ {
@ -892,6 +908,10 @@ void UVRSliderComponent::SetSplineComponentToFollow(USplineComponent * SplineToF
{ {
SplineComponentToFollow = SplineToFollow; SplineComponentToFollow = SplineToFollow;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, SplineComponentToFollow, this);
#endif
if (SplineToFollow != nullptr) if (SplineToFollow != nullptr)
ResetToParentSplineLocation(); ResetToParentSplineLocation();
else else
@ -902,6 +922,11 @@ void UVRSliderComponent::ResetInitialSliderLocation()
{ {
// Get our initial relative transform to our parent (or not if un-parented). // Get our initial relative transform to our parent (or not if un-parented).
InitialRelativeTransform = this->GetRelativeTransform(); InitialRelativeTransform = this->GetRelativeTransform();
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, InitialRelativeTransform, this);
#endif
ResetToParentSplineLocation(); ResetToParentSplineLocation();
if (SplineComponentToFollow == nullptr) if (SplineComponentToFollow == nullptr)
@ -986,3 +1011,31 @@ float UVRSliderComponent::CalculateSliderProgress()
return CurrentSliderProgress; return CurrentSliderProgress;
} }
void UVRSliderComponent::SetRepGameplayTags(bool bNewRepGameplayTags)
{
bRepGameplayTags = bNewRepGameplayTags;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, bRepGameplayTags, this);
#endif
}
void UVRSliderComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, bReplicateMovement, this);
#endif
}
FGameplayTagContainer& UVRSliderComponent::GetGameplayTags()
{
#if WITH_PUSH_MODEL
if (bRepGameplayTags)
{
MARK_PROPERTY_DIRTY_FROM_NAME(UVRSliderComponent, GameplayTags, this);
}
#endif
return GameplayTags;
}

View file

@ -4,6 +4,7 @@
#include UE_INLINE_GENERATED_CPP_BY_NAME(CollisionIgnoreSubsystem) #include UE_INLINE_GENERATED_CPP_BY_NAME(CollisionIgnoreSubsystem)
#include "Components/SkeletalMeshComponent.h" #include "Components/SkeletalMeshComponent.h"
#include "Engine/World.h"
#include "Runtime/Engine/Classes/Kismet/GameplayStatics.h" #include "Runtime/Engine/Classes/Kismet/GameplayStatics.h"
#include "VRGlobalSettings.h" #include "VRGlobalSettings.h"
@ -92,6 +93,16 @@ void UCollisionIgnoreSubsystem::ConstructInput()
} }
} }
void UCollisionIgnoreSubsystem::Deinitialize()
{
Super::Deinitialize();
if (UpdateHandle.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(UpdateHandle);
}
}
void UCollisionIgnoreSubsystem::UpdateTimer(bool bChangesWereMade) void UCollisionIgnoreSubsystem::UpdateTimer(bool bChangesWereMade)
{ {

View file

@ -30,7 +30,10 @@ void UNoRepSphereComponent::GetLifetimeReplicatedProps(TArray< class FLifetimePr
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UNoRepSphereComponent, bReplicateMovement); // For std properties
FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UNoRepSphereComponent, bReplicateMovement, PushModelParams);
RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachParent, COND_InitialOnly); RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachParent, COND_InitialOnly);
RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachSocketName, COND_InitialOnly); RESET_REPLIFETIME_CONDITION_PRIVATE_PROPERTY(USceneComponent, AttachSocketName, COND_InitialOnly);
@ -41,6 +44,14 @@ void UNoRepSphereComponent::GetLifetimeReplicatedProps(TArray< class FLifetimePr
//DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication); //DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
} }
void UNoRepSphereComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UNoRepSphereComponent, bReplicateMovement, this);
#endif
}
void UNoRepSphereComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) void UNoRepSphereComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
{ {
Super::PreReplication(ChangedPropertyTracker); Super::PreReplication(ChangedPropertyTracker);
@ -95,6 +106,15 @@ void UInversePhysicsSkeletalMeshComponent::PreReplication(IRepChangedPropertyTra
DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement); DOREPLIFETIME_ACTIVE_OVERRIDE_FAST(USceneComponent, RelativeScale3D, bReplicateMovement);
} }
void UInversePhysicsSkeletalMeshComponent::SetReplicateMovement(bool bNewReplicateMovement)
{
bReplicateMovement = bNewReplicateMovement;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UInversePhysicsSkeletalMeshComponent, bReplicateMovement, this);
#endif
}
void UInversePhysicsSkeletalMeshComponent::EndPhysicsTickComponentVR(FSkeletalMeshComponentEndPhysicsTickFunctionVR& ThisTickFunction) void UInversePhysicsSkeletalMeshComponent::EndPhysicsTickComponentVR(FSkeletalMeshComponentEndPhysicsTickFunctionVR& ThisTickFunction)
{ {
//IMPORTANT! //IMPORTANT!
@ -632,7 +652,10 @@ void UInversePhysicsSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< cl
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(UInversePhysicsSkeletalMeshComponent, bReplicateMovement); // For std properties
FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UInversePhysicsSkeletalMeshComponent, bReplicateMovement, PushModelParams);
} }
AOptionalRepGrippableSkeletalMeshActor::AOptionalRepGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer) : AOptionalRepGrippableSkeletalMeshActor::AOptionalRepGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer) :
@ -646,8 +669,11 @@ void AOptionalRepGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray<
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME(AOptionalRepGrippableSkeletalMeshActor, bIgnoreAttachmentReplication); // For properties with special conditions
DOREPLIFETIME(AOptionalRepGrippableSkeletalMeshActor, bIgnorePhysicsReplication); FDoRepLifetimeParams PushModelParamsWithCondition{ COND_InitialOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AOptionalRepGrippableSkeletalMeshActor, bIgnoreAttachmentReplication, PushModelParamsWithCondition);
DOREPLIFETIME_WITH_PARAMS_FAST(AOptionalRepGrippableSkeletalMeshActor, bIgnorePhysicsReplication, PushModelParamsWithCondition);
if (bIgnoreAttachmentReplication) if (bIgnoreAttachmentReplication)
{ {

View file

@ -3,8 +3,11 @@
#include "Misc/VRAIPerceptionOverrides.h" #include "Misc/VRAIPerceptionOverrides.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRAIPerceptionOverrides) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRAIPerceptionOverrides)
#include "EngineDefines.h" #include "CoreMinimal.h"
#include "EngineGlobals.h" #include "Engine/Engine.h"
#include "Engine/World.h"
//#include "EngineDefines.h"
//#include "EngineGlobals.h"
#include "CollisionQueryParams.h" #include "CollisionQueryParams.h"
//#include "Engine/Engine.h" //#include "Engine/Engine.h"
#include "AISystem.h" #include "AISystem.h"
@ -45,12 +48,12 @@ DECLARE_CYCLE_STAT(TEXT("Perception Sense: Sight, Process pending result"), STAT
static const int32 DefaultMaxTracesPerTick = 6; constexpr int32 DefaultMaxTracesPerTick = 6;
static const int32 DefaultMaxAsyncTracesPerTick = 10; constexpr int32 DefaultMaxAsyncTracesPerTick = 10;
static const int32 DefaultMinQueriesPerTimeSliceCheck = 40; constexpr int32 DefaultMinQueriesPerTimeSliceCheck = 40;
static const float DefaultPendingQueriesBudgetReductionRatio = 0.5f; constexpr float DefaultPendingQueriesBudgetReductionRatio = 0.5f;
static const bool bDefaultUseAsynchronousTraceForDefaultSightQueries = false; constexpr bool bDefaultUseAsynchronousTraceForDefaultSightQueries = false;
static const float DefaultStimulusStrength = 1.f; constexpr float DefaultStimulusStrength = 1.f;
enum class EForEachResult : uint8 enum class EForEachResult : uint8
{ {
@ -111,7 +114,7 @@ FORCEINLINE_DEBUGGABLE bool CheckIsTargetInSightPie(const FPerceptionListener& L
const FAISightTargetVR::FTargetId FAISightTargetVR::InvalidTargetId = FAISystem::InvalidUnsignedID; const FAISightTargetVR::FTargetId FAISightTargetVR::InvalidTargetId = FAISystem::InvalidUnsignedID;
FAISightTargetVR::FAISightTargetVR(AActor* InTarget, FGenericTeamId InTeamId) FAISightTargetVR::FAISightTargetVR(AActor* InTarget, FGenericTeamId InTeamId)
: Target(InTarget), SightTargetInterface(NULL), TeamId(InTeamId) : Target(InTarget), SightTargetInterface(nullptr), TeamId(InTeamId)
{ {
if (InTarget) if (InTarget)
{ {
@ -139,8 +142,10 @@ UAISense_Sight_VR::FDigestedSightProperties::FDigestedSightProperties(const UAIS
} }
UAISense_Sight_VR::FDigestedSightProperties::FDigestedSightProperties() UAISense_Sight_VR::FDigestedSightProperties::FDigestedSightProperties()
: PeripheralVisionAngleCos(0.f), SightRadiusSq(-1.f), AutoSuccessRangeSqFromLastSeenLocation(FAISystem::InvalidRange), LoseSightRadiusSq(-1.f), PointOfViewBackwardOffset(0.0f), NearClippingRadiusSq(0.0f), AffiliationFlags(-1) : PeripheralVisionAngleCos(0.f), SightRadiusSq(-1.f), AutoSuccessRangeSqFromLastSeenLocation(FAISystem::InvalidRange), LoseSightRadiusSq(-1.f), PointOfViewBackwardOffset(0.0f), NearClippingRadiusSq(0.0f)
{} {
AffiliationFlags = FAISenseAffiliationFilter::DetectAllFlags();
}
//----------------------------------------------------------------------// //----------------------------------------------------------------------//
@ -338,7 +343,7 @@ float UAISense_Sight_VR::Update()
#if AISENSE_SIGHT_TIMESLICING_DEBUG #if AISENSE_SIGHT_TIMESLICING_DEBUG
UE::AISense_SightVR::FTimingSlicingInfo SlicingInfo; UE::AISense_SightVR::FTimingSlicingInfo SlicingInfo;
#endif // AISENSE_SIGHT_TIMESLICING_DEBUG #endif // AISENSE_SIGHT_TIMESLICING_DEBUG
static const int32 InitialInvalidItemsSize = 16; constexpr int32 InitialInvalidItemsSize = 16;
enum class EOperationType : uint8 enum class EOperationType : uint8
{ {
Remove, Remove,
@ -488,7 +493,7 @@ float UAISense_Sight_VR::Update()
}); });
// Do all the removes first and save the out of range swaps because we will insert them at the right location to prevent sorting // Do all the removes first and save the out of range swaps because we will insert them at the right location to prevent sorting
TArray<FAISightQueryVR> SightQueriesOutOfRangeToInsert; TArray<FAISightQueryVR> SightQueriesOutOfRangeToInsert;
for (FQueryOperation& Operation : QueryOperations) for (const FQueryOperation& Operation : QueryOperations)
{ {
switch (Operation.OpType) switch (Operation.OpType)
{ {
@ -520,12 +525,12 @@ float UAISense_Sight_VR::Update()
if (Operation.bInRange) if (Operation.bInRange)
{ {
// In range queries are always sorted at the beginning of the update // In range queries are always sorted at the beginning of the update
SightQueriesInRange.RemoveAtSwap(Operation.Index, 1, /*bAllowShrinking*/false); SightQueriesInRange.RemoveAtSwap(Operation.Index, 1, EAllowShrinking::No);
} }
else else
{ {
// Preserve the list ordered // Preserve the list ordered
SightQueriesOutOfRange.RemoveAt(Operation.Index, 1, /*bAllowShrinking*/false); SightQueriesOutOfRange.RemoveAt(Operation.Index, 1, EAllowShrinking::No);
if (Operation.Index < NextOutOfRangeIndex) if (Operation.Index < NextOutOfRangeIndex)
{ {
NextOutOfRangeIndex--; NextOutOfRangeIndex--;
@ -547,7 +552,7 @@ float UAISense_Sight_VR::Update()
for (const auto& TargetId : InvalidTargets) for (const auto& TargetId : InvalidTargets)
{ {
// remove affected queries // remove affected queries
RemoveAllQueriesToTarget(TargetId); RemoveAllQueriesToTarget_Internal(TargetId);
// remove target itself // remove target itself
ObservedTargets.Remove(TargetId); ObservedTargets.Remove(TargetId);
} }
@ -751,7 +756,7 @@ void UAISense_Sight_VR::OnPendingTraceQueryProcessed(const FTraceHandle& TraceHa
void UAISense_Sight_VR::OnPendingQueryProcessed(const int32 SightQueryIndex, const bool bIsVisible, const float StimulusStrength, const FVector& SeenLocation, const TOptional<int32>& UserData, const TOptional<AActor*> InTargetActor) void UAISense_Sight_VR::OnPendingQueryProcessed(const int32 SightQueryIndex, const bool bIsVisible, const float StimulusStrength, const FVector& SeenLocation, const TOptional<int32>& UserData, const TOptional<AActor*> InTargetActor)
{ {
FAISightQueryVR SightQuery = SightQueriesPending[SightQueryIndex]; FAISightQueryVR SightQuery = SightQueriesPending[SightQueryIndex];
SightQueriesPending.RemoveAtSwap(SightQueryIndex, 1, false); SightQueriesPending.RemoveAtSwap(SightQueryIndex, 1, EAllowShrinking::No);
AIPerception::FListenerMap& ListenersMap = *GetListeners(); AIPerception::FListenerMap& ListenersMap = *GetListeners();
FPerceptionListener* Listener = ListenersMap.Find(SightQuery.ObserverId); FPerceptionListener* Listener = ListenersMap.Find(SightQuery.ObserverId);
@ -855,7 +860,7 @@ void UAISense_Sight_VR::UnregisterSource(AActor& SourceActor)
Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 0.f, SightQuery->LastSeenLocation, Listener.CachedLocation, FAIStimulus::SensingFailed)); Listener.RegisterStimulus(TargetActor, FAIStimulus(*this, 0.f, SightQuery->LastSeenLocation, Listener.CachedLocation, FAIStimulus::SensingFailed));
} }
SightQueries.RemoveAtSwap(QueryIndex, 1, /*bAllowShrinking=*/false); SightQueries.RemoveAtSwap(QueryIndex, 1, EAllowShrinking::No);
return EReverseForEachResult::Modified; return EReverseForEachResult::Modified;
} }
@ -1015,7 +1020,7 @@ void UAISense_Sight_VR::OnListenerUpdateImpl(const FPerceptionListener& UpdatedL
// see if this listener is a Target as well // see if this listener is a Target as well
const FAISightTargetVR::FTargetId AsTargetId = UpdatedListener.GetBodyActorUniqueID(); const FAISightTargetVR::FTargetId AsTargetId = UpdatedListener.GetBodyActorUniqueID();
FAISightTargetVR* AsTarget = ObservedTargets.Find(AsTargetId); FAISightTargetVR* AsTarget = ObservedTargets.Find(AsTargetId);
if (AsTarget != NULL) if (AsTarget != nullptr)
{ {
if (AsTarget->Target.IsValid()) if (AsTarget->Target.IsValid())
{ {
@ -1126,13 +1131,11 @@ void UAISense_Sight_VR::RemoveAllQueriesByListener(const FPerceptionListener& Li
{ {
OnRemoveFunc(SightQuery); OnRemoveFunc(SightQuery);
} }
SightQueries.RemoveAtSwap(QueryIndex, 1, /*bAllowShrinking=*/false); SightQueries.RemoveAtSwap(QueryIndex, 1, EAllowShrinking::No);
return EReverseForEachResult::Modified; return EReverseForEachResult::Modified;
} }
return EReverseForEachResult::UnTouched; return EReverseForEachResult::UnTouched;
}; };
ReverseForEach(SightQueriesInRange, RemoveQuery); ReverseForEach(SightQueriesInRange, RemoveQuery);
@ -1148,6 +1151,12 @@ void UAISense_Sight_VR::RemoveAllQueriesToTarget(const FAISightTargetVR::FTarget
{ {
SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RemoveToTarget); SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RemoveToTarget);
UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector); UE_MT_SCOPED_WRITE_ACCESS(QueriesListAccessDetector);
RemoveAllQueriesToTarget_Internal(TargetId, OnRemoveFunc);
}
void UAISense_Sight_VR::RemoveAllQueriesToTarget_Internal(const FAISightTargetVR::FTargetId& TargetId, const TFunction<void(const FAISightQueryVR&)>& OnRemoveFunc/*= nullptr */)
{
SCOPE_CYCLE_COUNTER(STAT_AI_Sense_Sight_RemoveToTarget);
auto RemoveQuery = [&TargetId, &OnRemoveFunc](TArray<FAISightQueryVR>& SightQueries, const int32 QueryIndex)->EReverseForEachResult auto RemoveQuery = [&TargetId, &OnRemoveFunc](TArray<FAISightQueryVR>& SightQueries, const int32 QueryIndex)->EReverseForEachResult
{ {
@ -1159,7 +1168,7 @@ void UAISense_Sight_VR::RemoveAllQueriesToTarget(const FAISightTargetVR::FTarget
{ {
OnRemoveFunc(SightQuery); OnRemoveFunc(SightQuery);
} }
SightQueries.RemoveAtSwap(QueryIndex, 1, /*bAllowShrinking=*/false); SightQueries.RemoveAtSwap(QueryIndex, 1, EAllowShrinking::No);
return EReverseForEachResult::Modified; return EReverseForEachResult::Modified;
} }

View file

@ -8,9 +8,11 @@
#include "ReferenceSkeleton.h" #include "ReferenceSkeleton.h"
#include "DrawDebugHelpers.h" #include "DrawDebugHelpers.h"
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
#include "Chaos/ImplicitObject.h" #include "Chaos/ImplicitObject.h"
#include "Chaos/TriangleMeshImplicitObject.h" #include "Chaos/TriangleMeshImplicitObject.h"
#include "Chaos/ShapeInstance.h"
#include "Chaos/DebugDrawQueue.h"
#endif #endif
#include "Physics/PhysicsInterfaceCore.h" #include "Physics/PhysicsInterfaceCore.h"
@ -231,8 +233,8 @@ void UVREPhysicalAnimationComponent::UpdateWeldedBoneDriver(float DeltaTime)
if (FPhysicsInterface::IsValid(ActorHandle) /*&& FPhysicsInterface::IsRigidBody(ActorHandle)*/) if (FPhysicsInterface::IsValid(ActorHandle) /*&& FPhysicsInterface::IsRigidBody(ActorHandle)*/)
{ {
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
if (bDebugDrawCollision) if (false)//bDebugDrawCollision)
{ {
Chaos::FDebugDrawQueue::GetInstance().SetConsumerActive(this, true); // Need to deactivate this later as well Chaos::FDebugDrawQueue::GetInstance().SetConsumerActive(this, true); // Need to deactivate this later as well
Chaos::FDebugDrawQueue::GetInstance().SetMaxCost(20000); Chaos::FDebugDrawQueue::GetInstance().SetMaxCost(20000);
@ -251,8 +253,8 @@ void UVREPhysicalAnimationComponent::UpdateWeldedBoneDriver(float DeltaTime)
FTransform GlobalPoseInv = GlobalPose.Inverse(); FTransform GlobalPoseInv = GlobalPose.Inverse();
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
if (bDebugDrawCollision) if (false)//bDebugDrawCollision)
{ {
Chaos::FDebugDrawQueue::GetInstance().SetRegionOfInterest(GlobalPose.GetLocation(), 100.0f); Chaos::FDebugDrawQueue::GetInstance().SetRegionOfInterest(GlobalPose.GetLocation(), 100.0f);
} }
@ -305,33 +307,33 @@ void UVREPhysicalAnimationComponent::UpdateWeldedBoneDriver(float DeltaTime)
} }
} }
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
if (bDebugDrawCollision) if (false)//bDebugDrawCollision)
{ {
const Chaos::FImplicitObject* ShapeImplicit = Shape.Shape->GetGeometry().Get(); /*const Chaos::FImplicitObject& ShapeImplicit = Shape.GetGeometry();
Chaos::EImplicitObjectType Type = ShapeImplicit->GetType(); Chaos::EImplicitObjectType Type = ShapeImplicit.GetType();
FTransform shapeTransform = FPhysicsInterface::GetLocalTransform(Shape); FTransform shapeTransform = FPhysicsInterface::GetLocalTransform(Shape);
FTransform FinalTransform = shapeTransform * GlobalPose; FTransform FinalTransform = shapeTransform * GlobalPose;
Chaos::FRigidTransform3 RigTransform(FinalTransform); Chaos::FRigidTransform3 RigTransform(FinalTransform);
Chaos::DebugDraw::DrawShape(RigTransform, ShapeImplicit, Chaos::FShapeOrShapesArray(), FColor::White); Chaos::DebugDraw::DrawShape(RigTransform, &ShapeImplicit, Shape.Shape, FColor::White);*/
} }
#endif #endif
} }
}); });
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
if (bDebugDrawCollision) if (false)//bDebugDrawCollision)
{ {
// Get the latest commands // Get the latest commands
TArray<Chaos::FLatentDrawCommand> DrawCommands; /*TArray<Chaos::FLatentDrawCommand> DrawCommands;
Chaos::FDebugDrawQueue::GetInstance().ExtractAllElements(DrawCommands); Chaos::FDebugDrawQueue::GetInstance().ExtractAllElements(DrawCommands);
if (DrawCommands.Num()) if (DrawCommands.Num())
{ {
DebugDrawMesh(DrawCommands); DebugDrawMesh(DrawCommands);
} }
Chaos::FDebugDrawQueue::GetInstance().SetConsumerActive(this, false); // Need to deactivate this later as well Chaos::FDebugDrawQueue::GetInstance().SetConsumerActive(this, false); // Need to deactivate this later as well
Chaos::FDebugDrawQueue::GetInstance().SetEnabled(false); Chaos::FDebugDrawQueue::GetInstance().SetEnabled(false);*/
} }
#endif #endif
} }
@ -341,7 +343,8 @@ void UVREPhysicalAnimationComponent::UpdateWeldedBoneDriver(float DeltaTime)
} }
} }
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
/*
void UVREPhysicalAnimationComponent::DebugDrawMesh(const TArray<Chaos::FLatentDrawCommand>& DrawCommands) void UVREPhysicalAnimationComponent::DebugDrawMesh(const TArray<Chaos::FLatentDrawCommand>& DrawCommands)
{ {
UWorld* World = this->GetWorld(); UWorld* World = this->GetWorld();
@ -382,5 +385,5 @@ void UVREPhysicalAnimationComponent::DebugDrawMesh(const TArray<Chaos::FLatentDr
break; break;
} }
} }
} }*/
#endif #endif

View file

@ -4,7 +4,7 @@
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRFullScreenUserWidget) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRFullScreenUserWidget)
//#include "Components/PostProcessComponent.h" //#include "Components/PostProcessComponent.h"
//#include "Engine/Engine.h" #include "Engine/Engine.h"
#include "Engine/GameInstance.h" #include "Engine/GameInstance.h"
#include "Engine/GameViewportClient.h" #include "Engine/GameViewportClient.h"
#include "Engine/TextureRenderTarget2D.h" #include "Engine/TextureRenderTarget2D.h"

View file

@ -3,6 +3,9 @@
#include "Misc/VRLogComponent.h" #include "Misc/VRLogComponent.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRLogComponent) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRLogComponent)
#include "Engine/Engine.h"
#include "GenericPlatform\GenericPlatformInputDeviceMapper.h"
#include "Engine\GameViewportClient.h"
#include "GlobalRenderResources.h" #include "GlobalRenderResources.h"
//#include "Engine/Engine.h" //#include "Engine/Engine.h"

View file

@ -3,6 +3,8 @@
#include "Misc/VRPlayerStart.h" #include "Misc/VRPlayerStart.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRPlayerStart) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRPlayerStart)
#include "CoreMinimal.h"
#include "Engine/World.h"
#include "Components/CapsuleComponent.h" #include "Components/CapsuleComponent.h"
#include "Components/BillboardComponent.h" #include "Components/BillboardComponent.h"

View file

@ -3,12 +3,17 @@
#include "Misc/VRRenderTargetManager.h" #include "Misc/VRRenderTargetManager.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRRenderTargetManager) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRRenderTargetManager)
#include "Engine/World.h"
#include "GlobalRenderResources.h"
#include "Components/ActorComponent.h"
#include "Kismet/GameplayStatics.h" #include "Kismet/GameplayStatics.h"
#include "GameFramework\Pawn.h"
#include "GameFramework/PlayerState.h" #include "GameFramework/PlayerState.h"
#include "GameFramework/PlayerController.h" #include "GameFramework/PlayerController.h"
#include "Engine/TextureRenderTarget2D.h" #include "Engine/TextureRenderTarget2D.h"
#include "Engine/Texture2D.h" #include "Engine/Texture2D.h"
#include "TextureResource.h" #include "TextureResource.h"
#include "PixelFormat.h"
#include "CanvasTypes.h" #include "CanvasTypes.h"
#include "Kismet/KismetMathLibrary.h" #include "Kismet/KismetMathLibrary.h"
#include "Kismet/KismetRenderingLibrary.h" #include "Kismet/KismetRenderingLibrary.h"
@ -279,7 +284,7 @@ void UVRRenderTargetManager::DrawOperations()
UWorld* World = GetWorld(); UWorld* World = GetWorld();
if (!World || !World->bBegunPlay) if (!World || !World->GetBegunPlay())
return; return;
// Reference to the Render Target resource // Reference to the Render Target resource
@ -485,14 +490,24 @@ void ARenderTargetReplicationProxy::SendNextDataBlob()
} }
} }
void ARenderTargetReplicationProxy::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (SendTimer_Handle.IsValid())
GetWorld()->GetTimerManager().ClearTimer(SendTimer_Handle);
Super::EndPlay(EndPlayReason);
}
//============================================================================= //=============================================================================
void ARenderTargetReplicationProxy::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const void ARenderTargetReplicationProxy::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_InitialOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME(ARenderTargetReplicationProxy, OwningManager); DOREPLIFETIME_WITH_PARAMS_FAST(ARenderTargetReplicationProxy, OwningManager, PushModelParamsWithCondition);
DOREPLIFETIME(ARenderTargetReplicationProxy, OwnersID); DOREPLIFETIME_WITH_PARAMS_FAST(ARenderTargetReplicationProxy, OwnersID, PushModelParamsWithCondition);
} }
void ARenderTargetReplicationProxy::ReceiveTextureBlob_Implementation(const TArray<uint8>& TextureBlob, int32 LocationInData, int32 BlobNumber) void ARenderTargetReplicationProxy::ReceiveTextureBlob_Implementation(const TArray<uint8>& TextureBlob, int32 LocationInData, int32 BlobNumber)

View file

@ -0,0 +1,207 @@
#include "Mover/VRMoverComponent.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRMoverComponent)
#include "VRBPDatatypes.h"
#include "DefaultMovementSet\LayeredMoves\BasicLayeredMoves.h"
#include "Engine/BlueprintGeneratedClass.h"
#include "Curves\CurveFloat.h" // Delete after tests, only needed for cloning
#include "ReplicatedVRCameraComponent.h"
DEFINE_LOG_CATEGORY(LogVRMoverComponent);
static const FName Name_CharacterMotionComponent(TEXT("MoverComponent"));
/*
Layered move to inject VR movement into the mover component
*/
FLayeredMove_VRMovement::FLayeredMove_VRMovement()
: Velocity(FVector::ZeroVector)
, MagnitudeOverTime(nullptr)
, SettingsFlags(0)
{
// This should never end
DurationMs = -1.0f;
}
bool FLayeredMove_VRMovement::IsFinished(float CurrentSimTimeMs) const
{
// We never end the VR velocity injection
return false;
}
bool FLayeredMove_VRMovement::GenerateMove(const FMoverTickStartData& SimState, const FMoverTimeStep& TimeStep, const UMoverComponent* MoverComp, UMoverBlackboard* SimBlackboard, FProposedMove& OutProposedMove)
{
const FMoverDefaultSyncState* SyncState = SimState.SyncState.SyncStateCollection.FindDataByType<FMoverDefaultSyncState>();
check(SyncState);
const float DeltaSeconds = TimeStep.StepMs * 0.001f;
// Convert starting velocity based on starting orientation, if settings call for it
if (SettingsFlags & (uint8)ELayeredMove_ConstantVelocitySettingsFlags::VelocityStartRelative &&
StartSimTimeMs == TimeStep.BaseSimTimeMs)
{
SettingsFlags &= ~(uint8)ELayeredMove_ConstantVelocitySettingsFlags::VelocityStartRelative;
Velocity = SyncState->GetOrientation_WorldSpace().RotateVector(Velocity);
}
FVector VelocityThisFrame = Velocity;
// Put velocity into worldspace
if (SettingsFlags & (uint8)ELayeredMove_ConstantVelocitySettingsFlags::VelocityAlwaysRelative)
{
VelocityThisFrame = SyncState->GetOrientation_WorldSpace().RotateVector(Velocity);
}
if (MagnitudeOverTime && DurationMs > 0)
{
const float TimeValue = DurationMs > 0.f ? FMath::Clamp((TimeStep.BaseSimTimeMs - StartSimTimeMs) / DurationMs, 0.f, 1.f) : TimeStep.BaseSimTimeMs;
const float TimeFactor = MagnitudeOverTime->GetFloatValue(TimeValue);
VelocityThisFrame *= TimeFactor;
}
OutProposedMove.LinearVelocity = VelocityThisFrame;
return true;
}
FLayeredMoveBase* FLayeredMove_VRMovement::Clone() const
{
FLayeredMove_VRMovement* CopyPtr = new FLayeredMove_VRMovement(*this);
return CopyPtr;
}
void FLayeredMove_VRMovement::NetSerialize(FArchive& Ar)
{
Super::NetSerialize(Ar);
SerializePackedVector<10, 16>(Velocity, Ar);
Ar << SettingsFlags;
Ar << MagnitudeOverTime;
}
UScriptStruct* FLayeredMove_VRMovement::GetScriptStruct() const
{
return FLayeredMove_VRMovement::StaticStruct();
}
FString FLayeredMove_VRMovement::ToSimpleString() const
{
return FString::Printf(TEXT("LinearVelocity"));
}
void FLayeredMove_VRMovement::AddReferencedObjects(class FReferenceCollector& Collector)
{
Super::AddReferencedObjects(Collector);
}
/*
VR HMD Sync State to store the HMD velocities
Which should be pulled from input somehow
*/
FMoverDataStructBase* FVRMoverHMDSyncState::Clone() const
{
// TODO: ensure that this memory allocation jives with deletion method
FVRMoverHMDSyncState* CopyPtr = new FVRMoverHMDSyncState(*this);
return CopyPtr;
}
bool FVRMoverHMDSyncState::NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess)
{
Super::NetSerialize(Ar, Map, bOutSuccess);
SerializeFixedVector<2, 8>(MoveDirectionIntent, Ar);
bOutSuccess = true;
return true;
}
AVRMoverBasePawn::AVRMoverBasePawn(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
{
CharacterMotionComponent = CreateDefaultSubobject<UMoverComponent>(Name_CharacterMotionComponent);
ensure(CharacterMotionComponent);
// Set this pawn to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
SetReplicatingMovement(false); // disable Actor-level movement replication, since our Mover component will handle it
// Let the code know if blueprints have implemented input
auto IsImplementedInBlueprint = [](const UFunction* Func) -> bool
{
return Func && ensure(Func->GetOuter())
&& Func->GetOuter()->IsA(UBlueprintGeneratedClass::StaticClass());
};
static FName ProduceInputBPFuncName = FName(TEXT("OnProduceInputInBlueprint"));
UFunction* ProduceInputFunction = GetClass()->FindFunctionByName(ProduceInputBPFuncName);
bHasProduceInputinBpFunc = IsImplementedInBlueprint(ProduceInputFunction);
}
void AVRMoverBasePawn::BeginPlay()
{
Super::BeginPlay();
// In constructor for the data instead of begin play? Might even be able to queue the layered move there too
if (IsValid(CharacterMotionComponent))
{
// Add the sync data for our layered HMD movement injection
CharacterMotionComponent->PersistentSyncStateDataTypes.Add(FMoverDataPersistence(FVRMoverHMDSyncState::StaticStruct(), true));
// Needs to be handled off of possession instead?
if (HasLocalNetOwner())
{
// Add the persistant HMDlayered move addition
TSharedPtr<FLayeredMove_VRMovement> VRMoveLayer = MakeShared<FLayeredMove_VRMovement>();
CharacterMotionComponent->QueueLayeredMove(VRMoveLayer);
}
}
}
UPrimitiveComponent* AVRMoverBasePawn::GetMovementBase() const
{
return CharacterMotionComponent ? CharacterMotionComponent->GetMovementBase() : nullptr;
}
void AVRMoverBasePawn::ProduceInput_Implementation(int32 SimTimeMs, FMoverInputCmdContext& InputCmdResult)
{
OnProduceInput((float)SimTimeMs, InputCmdResult);
if (bHasProduceInputinBpFunc)
{
InputCmdResult = OnProduceInputInBlueprint((float)SimTimeMs, InputCmdResult);
}
}
void AVRMoverBasePawn::OnProduceInput(float DeltaMs, FMoverInputCmdContext& OutInputCmd)
{
// Generate user commands. Called right before the Character movement simulation will tick (for a locally controlled pawn)
// This isn't meant to be the best way of doing a camera system. It is just meant to show a couple of ways it may be done
// and to make sure we can keep distinct the movement, rotation, and view angles.
// Styles 1-3 are really meant to be used with a gamepad.
//
// Its worth calling out: the code that happens here is happening *outside* of the Character movement simulation. All we are doing
// is generating the input being fed into that simulation. That said, this means that A) the code below does not run on the server
// (and non controlling clients) and B) the code is not rerun during reconcile/resimulates. Use this information guide any
// decisions about where something should go (such as aim assist, lock on targeting systems, etc): it is hard to give absolute
// answers and will depend on the game and its specific needs. In general, at this time, I'd recommend aim assist and lock on
// targeting systems to happen /outside/ of the system, i.e, here. But I can think of scenarios where that may not be ideal too.
//FCharacterDefaultInputs& CharacterInputs = OutInputCmd.InputCollection.FindOrAddMutableDataByType<FVRCharacterExtendedInputs>();
}

View file

@ -3,6 +3,7 @@
#include "ParentRelativeAttachmentComponent.h" #include "ParentRelativeAttachmentComponent.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(ParentRelativeAttachmentComponent) #include UE_INLINE_GENERATED_CPP_BY_NAME(ParentRelativeAttachmentComponent)
#include "Engine/Engine.h"
#include "VRBaseCharacter.h" #include "VRBaseCharacter.h"
#include "VRCharacter.h" #include "VRCharacter.h"
#include "IXRTrackingSystem.h" #include "IXRTrackingSystem.h"

View file

@ -3,6 +3,9 @@
#include "ReplicatedVRCameraComponent.h" #include "ReplicatedVRCameraComponent.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(ReplicatedVRCameraComponent) #include UE_INLINE_GENERATED_CPP_BY_NAME(ReplicatedVRCameraComponent)
#include "CoreMinimal.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "VRBaseCharacter.h" #include "VRBaseCharacter.h"
#include "VRCharacter.h" #include "VRCharacter.h"
@ -11,6 +14,9 @@
#include "IXRCamera.h" #include "IXRCamera.h"
#include "Rendering/MotionVectorSimulation.h" #include "Rendering/MotionVectorSimulation.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
UReplicatedVRCameraComponent::UReplicatedVRCameraComponent(const FObjectInitializer& ObjectInitializer) UReplicatedVRCameraComponent::UReplicatedVRCameraComponent(const FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer) : Super(ObjectInitializer)
@ -41,7 +47,6 @@ UReplicatedVRCameraComponent::UReplicatedVRCameraComponent(const FObjectInitiali
MaximumTrackedBounds = 1028; MaximumTrackedBounds = 1028;
bSetPositionDuringTick = false; bSetPositionDuringTick = false;
bSmoothReplicatedMotion = false;
bLerpingPosition = false; bLerpingPosition = false;
bReppedOnce = false; bReppedOnce = false;
@ -70,28 +75,27 @@ void UReplicatedVRCameraComponent::GetLifetimeReplicatedProps(TArray< class FLif
DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeRotation); DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeRotation);
DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D); DISABLE_REPLICATED_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_SkipOwner, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
// Skipping the owner with this as the owner will use the location directly // Skipping the owner with this as the owner will use the location directly
DOREPLIFETIME_CONDITION(UReplicatedVRCameraComponent, ReplicatedCameraTransform, COND_SkipOwner); DOREPLIFETIME_WITH_PARAMS_FAST(UReplicatedVRCameraComponent, ReplicatedCameraTransform, PushModelParamsWithCondition);
DOREPLIFETIME(UReplicatedVRCameraComponent, NetUpdateRate);
DOREPLIFETIME(UReplicatedVRCameraComponent, bSmoothReplicatedMotion); // For std properties
FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(UReplicatedVRCameraComponent, NetUpdateRate, PushModelParams);
//DOREPLIFETIME(UReplicatedVRCameraComponent, bSmoothReplicatedMotion); // This doesn't need to be replicated
//DOREPLIFETIME(UReplicatedVRCameraComponent, bReplicateTransform); //DOREPLIFETIME(UReplicatedVRCameraComponent, bReplicateTransform);
} }
// Just skipping this, it generates warnings for attached meshes when using this method of denying transform replication
/*void UReplicatedVRCameraComponent::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
{
Super::PreReplication(ChangedPropertyTracker);
// Don't ever replicate these, they are getting replaced by my custom send anyway
DOREPLIFETIME_ACTIVE_OVERRIDE(USceneComponent, RelativeLocation, false);
DOREPLIFETIME_ACTIVE_OVERRIDE(USceneComponent, RelativeRotation, false);
DOREPLIFETIME_ACTIVE_OVERRIDE(USceneComponent, RelativeScale3D, false);
}*/
void UReplicatedVRCameraComponent::Server_SendCameraTransform_Implementation(FBPVRComponentPosRep NewTransform) void UReplicatedVRCameraComponent::Server_SendCameraTransform_Implementation(FBPVRComponentPosRep NewTransform)
{ {
// Store new transform and trigger OnRep_Function // Store new transform and trigger OnRep_Function
ReplicatedCameraTransform = NewTransform; ReplicatedCameraTransform = NewTransform;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UReplicatedVRCameraComponent, ReplicatedCameraTransform, this);
#endif
// Don't call on rep on the server if the server controls this controller // Don't call on rep on the server if the server controls this controller
if (!bHasAuthority) if (!bHasAuthority)
@ -191,7 +195,7 @@ void UReplicatedVRCameraComponent::UpdateTracking(float DeltaTime)
{ {
if (HasTrackingParameters()) if (HasTrackingParameters())
{ {
ApplyTrackingParameters(Position); ApplyTrackingParameters(Position, true);
} }
ReplicatedCameraTransform.Position = Position; ReplicatedCameraTransform.Position = Position;
@ -403,6 +407,10 @@ void UReplicatedVRCameraComponent::TickComponent(float DeltaTime, enum ELevelTic
ReplicatedCameraTransform.Rotation = RelativeRot; ReplicatedCameraTransform.Rotation = RelativeRot;
} }
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UReplicatedVRCameraComponent, ReplicatedCameraTransform, this);
#endif
if (GetNetMode() == NM_Client) if (GetNetMode() == NM_Client)
{ {
AVRBaseCharacter* OwningChar = Cast<AVRBaseCharacter>(GetOwner()); AVRBaseCharacter* OwningChar = Cast<AVRBaseCharacter>(GetOwner());
@ -458,7 +466,7 @@ void UReplicatedVRCameraComponent::HandleXRCamera()
{ {
if (HasTrackingParameters()) if (HasTrackingParameters())
{ {
ApplyTrackingParameters(Position); ApplyTrackingParameters(Position, true);
} }
ReplicatedCameraTransform.Position = Position; ReplicatedCameraTransform.Position = Position;
@ -506,6 +514,11 @@ void UReplicatedVRCameraComponent::HandleXRCamera()
} }
} }
FTransform UReplicatedVRCameraComponent::GetHMDTrackingTransform()
{
return FTransform(ReplicatedCameraTransform.Rotation, ReplicatedCameraTransform.Position);
}
void UReplicatedVRCameraComponent::OnRep_ReplicatedCameraTransform() void UReplicatedVRCameraComponent::OnRep_ReplicatedCameraTransform()
{ {
if (GetNetMode() < ENetMode::NM_Client && HasTrackingParameters()) if (GetNetMode() < ENetMode::NM_Client && HasTrackingParameters())
@ -571,3 +584,18 @@ void UReplicatedVRCameraComponent::OnRep_ReplicatedCameraTransform()
else else
SetRelativeLocationAndRotation(CameraPosition, ReplicatedCameraTransform.Rotation); SetRelativeLocationAndRotation(CameraPosition, ReplicatedCameraTransform.Rotation);
} }
void UReplicatedVRCameraComponent::SetNetUpdateRate(float NewNetUpdateRate)
{
NetUpdateRate = NewNetUpdateRate;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(UReplicatedVRCameraComponent, NetUpdateRate, this);
#endif
}
bool UReplicatedVRCameraComponent::IsLocallyControlled() const
{
// I like epics new authority check more than my own
const AActor* MyOwner = GetOwner();
return MyOwner->HasLocalNetOwner();
}

View file

@ -4,6 +4,8 @@
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRAIController) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRAIController)
//#include "VRBPDatatypes.h" //#include "VRBPDatatypes.h"
#include "CoreMinimal.h"
#include "Engine/World.h"
#include "VRBaseCharacter.h" #include "VRBaseCharacter.h"
#include "Components/CapsuleComponent.h" #include "Components/CapsuleComponent.h"
#include "NetworkingDistanceConstants.h" // Needed for the LinOfSightTo function override to work #include "NetworkingDistanceConstants.h" // Needed for the LinOfSightTo function override to work

View file

@ -3,6 +3,9 @@
#include "VRBPDatatypes.h" #include "VRBPDatatypes.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRBPDatatypes) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRBPDatatypes)
#include "CoreMinimal.h"
#include "VRGlobalSettings.h"
#include "Components\PrimitiveComponent.h"
#include "HAL/IConsoleManager.h" #include "HAL/IConsoleManager.h"
#include "Chaos/ChaosEngineInterface.h" #include "Chaos/ChaosEngineInterface.h"
@ -113,7 +116,7 @@ FVector FBPEuroLowPassFilter::RunFilterSmoothing(const FVector &InRawValue, cons
} }
// Calculate the delta, if this is the first time then there is no delta // Calculate the delta, if this is the first time then there is no delta
const FVector Delta = RawFilter.bFirstTime == true ? FVector::ZeroVector : (InRawValue - RawFilter.PreviousRaw) * 1.0f / InDeltaTime; const FVector Delta = RawFilter.bFirstTime == true ? FVector::ZeroVector : (InRawValue - RawFilter.PreviousRaw) * 1.0 / InDeltaTime;
// Filter the delta to get the estimated // Filter the delta to get the estimated
const FVector Estimated = DeltaFilter.Filter(Delta, FVector(DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime))); const FVector Estimated = DeltaFilter.Filter(Delta, FVector(DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime)));
@ -154,11 +157,11 @@ FQuat FBPEuroLowPassFilterQuat::RunFilterSmoothing(const FQuat& InRawValue, cons
if (!RawFilter.bFirstTime) if (!RawFilter.bFirstTime)
{ {
Delta = (NewInVal - RawFilter.PreviousRaw) * (1.0f / InDeltaTime); Delta = (NewInVal - RawFilter.PreviousRaw) * (1.0 / InDeltaTime);
} }
float AlphaTau = DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime); double AlphaTau = DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime);
FQuat AlphaTauQ(AlphaTau, AlphaTau, AlphaTau, AlphaTau); FQuat AlphaTauQ(AlphaTau, AlphaTau, AlphaTau, AlphaTau);
const FQuat Estimated = DeltaFilter.Filter(Delta, AlphaTauQ); const FQuat Estimated = DeltaFilter.Filter(Delta, AlphaTauQ);
@ -198,7 +201,7 @@ FTransform FBPEuroLowPassFilterTrans::RunFilterSmoothing(const FTransform& InRaw
// Calculate the delta, if this is the first time then there is no delta // Calculate the delta, if this is the first time then there is no delta
FTransform Delta = FTransform::Identity; FTransform Delta = FTransform::Identity;
float Frequency = 1.0f / InDeltaTime; double Frequency = 1.0 / InDeltaTime;
if (!RawFilter.bFirstTime) if (!RawFilter.bFirstTime)
{ {
Delta.SetLocation((NewInVal.GetLocation() - RawFilter.PreviousRaw.GetLocation()) * Frequency); Delta.SetLocation((NewInVal.GetLocation() - RawFilter.PreviousRaw.GetLocation()) * Frequency);
@ -207,7 +210,7 @@ FTransform FBPEuroLowPassFilterTrans::RunFilterSmoothing(const FTransform& InRaw
} }
float AlphaTau = DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime); double AlphaTau = DeltaFilter.CalculateAlphaTau(DeltaCutoff, InDeltaTime);
FTransform AlphaTauQ(FQuat(AlphaTau, AlphaTau, AlphaTau, AlphaTau), FVector(AlphaTau), FVector(AlphaTau)); FTransform AlphaTauQ(FQuat(AlphaTau, AlphaTau, AlphaTau, AlphaTau), FVector(AlphaTau), FVector(AlphaTau));
const FTransform Estimated = DeltaFilter.Filter(Delta, AlphaTauQ); const FTransform Estimated = DeltaFilter.Filter(Delta, AlphaTauQ);
@ -219,3 +222,71 @@ FTransform FBPEuroLowPassFilterTrans::RunFilterSmoothing(const FTransform& InRaw
// Filter passed value // Filter passed value
return NewTrans; return NewTrans;
} }
bool FBPAdvancedPhysicsHandleSettings::FillTo(FBPActorPhysicsHandleInformation* HandleInfo, bool bModifyWithScalers) const
{
if (!HandleInfo)
return false;
float DampingMod = 0.0f;
float StiffnessMod = 0.0f;
float ADampingMod = 0.0f;
float AStiffnessMod = 0.0f;
const UVRGlobalSettings& VRSettings = *GetDefault<UVRGlobalSettings>();
if (VRSettings.bUseChaosTranslationScalers)
{
StiffnessMod = VRSettings.LinearDriveStiffnessScale;
DampingMod = VRSettings.LinearDriveDampingScale;
AStiffnessMod = VRSettings.AngularDriveStiffnessScale;
ADampingMod = VRSettings.AngularDriveDampingScale;
}
else
{
auto CVarLinearDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinearDriveStiffnessScale"));
auto CVarLinearDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.LinaearDriveDampingScale"));
auto CVarAngularDriveStiffnessScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveStiffnessScale"));
auto CVarAngularDriveDampingScale = IConsoleManager::Get().FindConsoleVariable(TEXT("p.Chaos.JointConstraint.AngularDriveDampingScale"));
StiffnessMod = CVarLinearDriveStiffnessScale->GetFloat();
DampingMod = CVarLinearDriveDampingScale->GetFloat();
AStiffnessMod = CVarAngularDriveStiffnessScale->GetFloat();
ADampingMod = CVarAngularDriveDampingScale->GetFloat();
}
XAxisSettings.FillTo(HandleInfo->LinConstraint.XDrive, DampingMod, StiffnessMod);
YAxisSettings.FillTo(HandleInfo->LinConstraint.YDrive, DampingMod, StiffnessMod);
ZAxisSettings.FillTo(HandleInfo->LinConstraint.ZDrive, DampingMod, StiffnessMod);
if ((SlerpSettings.bEnablePositionDrive || SlerpSettings.bEnableVelocityDrive))
{
HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::SLERP;
SlerpSettings.FillTo(HandleInfo->AngConstraint.SlerpDrive, ADampingMod, AStiffnessMod);
}
else
{
HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::TwistAndSwing;
TwistSettings.FillTo(HandleInfo->AngConstraint.TwistDrive, ADampingMod, AStiffnessMod);
SwingSettings.FillTo(HandleInfo->AngConstraint.SwingDrive, ADampingMod, AStiffnessMod);
}
return true;
}
AActor* FBPActorGripInformation::GetGrippedActor() const
{
return Cast<AActor>(GrippedObject);
}
UPrimitiveComponent* FBPActorGripInformation::GetGrippedComponent() const
{
return Cast<UPrimitiveComponent>(GrippedObject);
}
bool FBPActorGripInformation::operator==(const UPrimitiveComponent* Other) const
{
if (Other && GrippedObject && GrippedObject == (const UObject*)Other)
return true;
return false;
}

View file

@ -14,8 +14,13 @@
#include "VRPathFollowingComponent.h" #include "VRPathFollowingComponent.h"
#include "Net/UnrealNetwork.h" #include "Net/UnrealNetwork.h"
#include "XRMotionControllerBase.h" #include "XRMotionControllerBase.h"
#include "NavFilters/NavigationQueryFilter.h"
//#include "Runtime/Engine/Private/EnginePrivate.h" //#include "Runtime/Engine/Private/EnginePrivate.h"
#if WITH_PUSH_MODEL
#include "Net/Core/PushModel/PushModel.h"
#endif
DEFINE_LOG_CATEGORY(LogBaseVRCharacter); DEFINE_LOG_CATEGORY(LogBaseVRCharacter);
FName AVRBaseCharacter::LeftMotionControllerComponentName(TEXT("Left Grip Motion Controller")); FName AVRBaseCharacter::LeftMotionControllerComponentName(TEXT("Left Grip Motion Controller"));
@ -235,13 +240,24 @@ void AVRBaseCharacter::PostInitializeComponents()
void AVRBaseCharacter::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const void AVRBaseCharacter::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const
{ {
Super::GetLifetimeReplicatedProps(OutLifetimeProps); Super::GetLifetimeReplicatedProps(OutLifetimeProps);
DOREPLIFETIME_CONDITION(AVRBaseCharacter, SeatInformation, COND_None);
DOREPLIFETIME_CONDITION(AVRBaseCharacter, VRReplicateCapsuleHeight, COND_None); // For std properties
DOREPLIFETIME_CONDITION(AVRBaseCharacter, ReplicatedCapsuleHeight, COND_SimulatedOnly); FDoRepLifetimeParams PushModelParams{ COND_None, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, SeatInformation, PushModelParams);
DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, VRReplicateCapsuleHeight, PushModelParams);
// For properties with special conditions
FDoRepLifetimeParams PushModelParamsWithCondition{ COND_SimulatedOnly, REPNOTIFY_OnChanged, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, ReplicatedCapsuleHeight, PushModelParamsWithCondition);
DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, ReplicatedMovement); DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, ReplicatedMovement);
DOREPLIFETIME_CONDITION_NOTIFY(AVRBaseCharacter, ReplicatedMovementVR, COND_SimulatedOrPhysics, REPNOTIFY_Always); // For properties with special conditions
FDoRepLifetimeParams PushModelParamsReplicatedMovement{ COND_SimulatedOrPhysics, REPNOTIFY_Always, /*bIsPushBased=*/true };
DOREPLIFETIME_WITH_PARAMS_FAST(AVRBaseCharacter, ReplicatedMovementVR, PushModelParamsReplicatedMovement);
} }
void AVRBaseCharacter::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) void AVRBaseCharacter::PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker)
@ -283,6 +299,10 @@ void AVRBaseCharacter::Server_ReZeroSeating_Implementation(FTransform_NetQuantiz
SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z)); SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z));
} }
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, SeatInformation, this);
#endif
OnRep_SeatedCharInfo(); OnRep_SeatedCharInfo();
} }
@ -457,6 +477,10 @@ void AVRBaseCharacter::GatherCurrentMovement()
ReplicatedMovementVR.PausedTrackingLoc = PausedTrackingLoc; ReplicatedMovementVR.PausedTrackingLoc = PausedTrackingLoc;
ReplicatedMovementVR.PausedTrackingRot = PausedTrackingRot; ReplicatedMovementVR.PausedTrackingRot = PausedTrackingRot;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, ReplicatedMovementVR, this);
#endif
} }
@ -784,7 +808,7 @@ bool AVRBaseCharacter::SetSeatedMode(USceneComponent * SeatParent, bool bSetSeat
// I think we can remove the initial value alltogether eventually right? // I think we can remove the initial value alltogether eventually right?
if (!bRetainRoomscale && VRReplicatedCamera) if (!bRetainRoomscale && VRReplicatedCamera)
{ {
InitialRelCameraTransform = FTransform(VRReplicatedCamera->ReplicatedCameraTransform.Rotation, VRReplicatedCamera->ReplicatedCameraTransform.Position, VRReplicatedCamera->GetComponentScale()); InitialRelCameraTransform = VRReplicatedCamera->GetHMDTrackingTransform();
} }
SeatInformation.SeatParent = SeatParent; SeatInformation.SeatParent = SeatParent;
@ -805,6 +829,10 @@ bool AVRBaseCharacter::SetSeatedMode(USceneComponent * SeatParent, bool bSetSeat
SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z)); SeatInformation.StoredTargetTransform.AddToTranslation(FVector(0, 0, -newLocation.Z));
} }
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, SeatInformation, this);
#endif
//SetReplicateMovement(false);/ / No longer doing this, allowing it to replicate down to simulated clients now instead //SetReplicateMovement(false);/ / No longer doing this, allowing it to replicate down to simulated clients now instead
} }
else else
@ -815,6 +843,9 @@ bool AVRBaseCharacter::SetSeatedMode(USceneComponent * SeatParent, bool bSetSeat
//SetReplicateMovement(true); // No longer doing this, allowing it to replicate down to simulated clients now instead //SetReplicateMovement(true); // No longer doing this, allowing it to replicate down to simulated clients now instead
SeatInformation.bSitting = false; SeatInformation.bSitting = false;
} }
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, SeatInformation, this);
#endif
OnRep_SeatedCharInfo(); // Call this on server side because it won't call itself OnRep_SeatedCharInfo(); // Call this on server side because it won't call itself
NotifyOfTeleport(); // Teleport the controllers NotifyOfTeleport(); // Teleport the controllers
@ -1205,3 +1236,11 @@ void AVRBaseCharacter::StopNavigationMovement()
pathComp->AbortMove(*this, FPathFollowingResultFlags::MovementStop | FPathFollowingResultFlags::ForcedScript); pathComp->AbortMove(*this, FPathFollowingResultFlags::MovementStop | FPathFollowingResultFlags::ForcedScript);
} }
} }
void AVRBaseCharacter::SetVRReplicateCapsuleHeight(bool bNewVRReplicateCapsuleHeight)
{
VRReplicateCapsuleHeight = bNewVRReplicateCapsuleHeight;
#if WITH_PUSH_MODEL
MARK_PROPERTY_DIRTY_FROM_NAME(AVRBaseCharacter, VRReplicateCapsuleHeight, this);
#endif
}

View file

@ -19,6 +19,7 @@
#include "Navigation/PathFollowingComponent.h" #include "Navigation/PathFollowingComponent.h"
#include "VRPlayerController.h" #include "VRPlayerController.h"
#include "GameFramework/PhysicsVolume.h" #include "GameFramework/PhysicsVolume.h"
#include "Animation\AnimInstance.h"
DEFINE_LOG_CATEGORY(LogVRBaseCharacterMovement); DEFINE_LOG_CATEGORY(LogVRBaseCharacterMovement);
@ -1621,10 +1622,16 @@ void UVRBaseCharacterMovementComponent::OnClientCorrectionReceived(class FNetwor
BaseVRCharacterOwner->OnCharacterNetworkCorrected_Bind.Broadcast(); BaseVRCharacterOwner->OnCharacterNetworkCorrected_Bind.Broadcast();
if (IsValid(BaseVRCharacterOwner->LeftMotionController)) if (IsValid(BaseVRCharacterOwner->LeftMotionController))
{
BaseVRCharacterOwner->LeftMotionController->TeleportMoveGrips(false, false); BaseVRCharacterOwner->LeftMotionController->TeleportMoveGrips(false, false);
BaseVRCharacterOwner->LeftMotionController->PostTeleportMoveGrippedObjects();
}
if (IsValid(BaseVRCharacterOwner->RightMotionController)) if (IsValid(BaseVRCharacterOwner->RightMotionController))
{
BaseVRCharacterOwner->RightMotionController->TeleportMoveGrips(false, false); BaseVRCharacterOwner->RightMotionController->TeleportMoveGrips(false, false);
BaseVRCharacterOwner->RightMotionController->PostTeleportMoveGrippedObjects();
}
//BaseVRCharacterOwner->NotifyOfTeleport(false); //BaseVRCharacterOwner->NotifyOfTeleport(false);
} }
} }
@ -1887,6 +1894,9 @@ void UVRBaseCharacterMovementComponent::MoveAutonomous(
const bool bWasPlayingRootMotion = CharacterOwner->IsPlayingRootMotion(); const bool bWasPlayingRootMotion = CharacterOwner->IsPlayingRootMotion();
// Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char
//const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner ? BaseVRCharacterOwner->NetSmoother : nullptr);
PerformMovement(DeltaTime); PerformMovement(DeltaTime);
// Check if data is valid as PerformMovement can mark character for pending kill // Check if data is valid as PerformMovement can mark character for pending kill
@ -1904,12 +1914,31 @@ void UVRBaseCharacterMovementComponent::MoveAutonomous(
} }
// TODO: SaveBaseLocation() in case tick moves us? // TODO: SaveBaseLocation() in case tick moves us?
USkeletalMeshComponent* OwnerMesh = CharacterOwner->GetMesh();
check(OwnerMesh != nullptr)
static const auto CVarEnableQueuedAnimEventsOnServer = IConsoleManager::Get().FindConsoleVariable(TEXT("a.EnableQueuedAnimEventsOnServer")); static const auto CVarEnableQueuedAnimEventsOnServer = IConsoleManager::Get().FindConsoleVariable(TEXT("a.EnableQueuedAnimEventsOnServer"));
if (!CVarEnableQueuedAnimEventsOnServer->GetInt() || CharacterOwner->GetMesh()->ShouldOnlyTickMontages(DeltaTime)) if (CVarEnableQueuedAnimEventsOnServer->GetInt())
{ {
// If we're not doing a full anim graph update on the server, if (const UAnimInstance* AnimInstance = OwnerMesh->GetAnimInstance())
// trigger events right away, as we could be receiving multiple ServerMoves per frame. {
CharacterOwner->GetMesh()->ConditionallyDispatchQueuedAnimEvents(); if (OwnerMesh->VisibilityBasedAnimTickOption <= EVisibilityBasedAnimTickOption::AlwaysTickPose && AnimInstance->NeedsUpdate())
{
// If we are doing a full graph update on the server but its doing a parallel update,
// trigger events right away since these are notifies queued from the montage update and we could be receiving multiple ServerMoves per frame.
OwnerMesh->ConditionallyDispatchQueuedAnimEvents();
OwnerMesh->AllowQueuedAnimEventsNextDispatch();
}
}
}
else
{
// Revert back to old behavior if wanted/needed.
if (OwnerMesh->ShouldOnlyTickMontages(DeltaTime))
{
OwnerMesh->ConditionallyDispatchQueuedAnimEvents();
}
} }
} }
@ -2229,9 +2258,10 @@ void UVRBaseCharacterMovementComponent::UpdateFromCompressedFlags(uint8 Flags)
FVector UVRBaseCharacterMovementComponent::RoundDirectMovement(FVector InMovement) const FVector UVRBaseCharacterMovementComponent::RoundDirectMovement(FVector InMovement) const
{ {
// Match FVector_NetQuantize100 (2 decimal place of precision). // Match FVector_NetQuantize100 (2 decimal place of precision).
InMovement.X = FMath::RoundToFloat(InMovement.X * 100.f) / 100.f; UE::Net::QuantizeVector(100, InMovement);
InMovement.Y = FMath::RoundToFloat(InMovement.Y * 100.f) / 100.f; //InMovement.X = FMath::RoundToFloat(InMovement.X * 100.f) / 100.f;
InMovement.Z = FMath::RoundToFloat(InMovement.Z * 100.f) / 100.f; //InMovement.Y = FMath::RoundToFloat(InMovement.Y * 100.f) / 100.f;
//InMovement.Z = FMath::RoundToFloat(InMovement.Z * 100.f) / 100.f;
return InMovement; return InMovement;
} }
@ -2378,5 +2408,5 @@ bool UVRBaseCharacterMovementComponent::SetCharacterToNewGravity(FVector NewGrav
return true; return true;
} }
return false; //return false;
} }

View file

@ -14,6 +14,7 @@
#include "GameFramework/Controller.h" #include "GameFramework/Controller.h"
#include "Runtime/Launch/Resources/Version.h" #include "Runtime/Launch/Resources/Version.h"
#include "VRPathFollowingComponent.h" #include "VRPathFollowingComponent.h"
#include "NavFilters/NavigationQueryFilter.h"
//#include "Runtime/Engine/Private/EnginePrivate.h" //#include "Runtime/Engine/Private/EnginePrivate.h"
DEFINE_LOG_CATEGORY(LogVRCharacter); DEFINE_LOG_CATEGORY(LogVRCharacter);
@ -197,6 +198,45 @@ FVector AVRCharacter::GetTargetHeightOffset()
return bRetainRoomscale ? FVector::ZeroVector : VRRootReference->GetTargetHeightOffset(); return bRetainRoomscale ? FVector::ZeroVector : VRRootReference->GetTargetHeightOffset();
} }
void AVRCharacter::OnStartCrouch(float HeightAdjust, float ScaledHeightAdjust)
{
RecalculateBaseEyeHeight();
/*const ACharacter* DefaultChar = GetDefault<ACharacter>(GetClass());
if (Mesh && DefaultChar->Mesh)
{
FVector& MeshRelativeLocation = Mesh->GetRelativeLocation_DirectMutable();
MeshRelativeLocation.Z = DefaultChar->Mesh->GetRelativeLocation().Z + HeightAdjust;
BaseTranslationOffset.Z = MeshRelativeLocation.Z;
}
else
{
BaseTranslationOffset.Z = DefaultChar->BaseTranslationOffset.Z + HeightAdjust;
}*/
K2_OnStartCrouch(HeightAdjust, ScaledHeightAdjust);
}
void AVRCharacter::OnEndCrouch(float HeightAdjust, float ScaledHeightAdjust)
{
RecalculateBaseEyeHeight();
/*const ACharacter* DefaultChar = GetDefault<ACharacter>(GetClass());
if (Mesh && DefaultChar->Mesh)
{
FVector& MeshRelativeLocation = Mesh->GetRelativeLocation_DirectMutable();
MeshRelativeLocation.Z = DefaultChar->Mesh->GetRelativeLocation().Z;
BaseTranslationOffset.Z = MeshRelativeLocation.Z;
}
else
{
BaseTranslationOffset.Z = DefaultChar->BaseTranslationOffset.Z;
}*/
K2_OnEndCrouch(HeightAdjust, ScaledHeightAdjust);
}
void AVRCharacter::RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw) void AVRCharacter::RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw)
{ {
if (VRRootReference) if (VRRootReference)

View file

@ -457,7 +457,7 @@ void FSavedMove_VRCharacter::PrepMoveFor(ACharacter* Character)
if (AVRBaseCharacter * BaseChar = Cast<AVRBaseCharacter>(CharMove->GetCharacterOwner())) if (AVRBaseCharacter * BaseChar = Cast<AVRBaseCharacter>(CharMove->GetCharacterOwner()))
{ {
if (BaseChar->VRReplicateCapsuleHeight && this->CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(this->CapsuleHeight, CharMove->VRRootCapsule->GetUnscaledCapsuleHalfHeight())) if (BaseChar->GetVRReplicateCapsuleHeight() && this->CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(this->CapsuleHeight, CharMove->VRRootCapsule->GetUnscaledCapsuleHalfHeight()))
{ {
BaseChar->SetCharacterHalfHeightVR(CapsuleHeight, false); BaseChar->SetCharacterHalfHeightVR(CapsuleHeight, false);
//CharMove->VRRootCapsule->SetCapsuleHalfHeight(this->LFDiff.Z, false); //CharMove->VRRootCapsule->SetCapsuleHalfHeight(this->LFDiff.Z, false);
@ -566,6 +566,10 @@ void UVRCharacterMovementComponent::ServerMove_PerformMovement(const FCharacterN
DeltaTime = ServerData->GetServerMoveDeltaTime(ClientTimeStamp, CharacterOwner->GetActorTimeDilation(*MyWorld)); DeltaTime = ServerData->GetServerMoveDeltaTime(ClientTimeStamp, CharacterOwner->GetActorTimeDilation(*MyWorld));
} }
// They added a scope here, im not using it as im doing the full capsule above
// Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char
//const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner ? BaseVRCharacterOwner->NetSmoother : nullptr);
if (DeltaTime > 0.f) if (DeltaTime > 0.f)
{ {
ServerData->CurrentClientTimeStamp = ClientTimeStamp; ServerData->CurrentClientTimeStamp = ClientTimeStamp;
@ -615,7 +619,7 @@ void UVRCharacterMovementComponent::ServerMove_PerformMovement(const FCharacterN
if (BaseVRCharacterOwner) if (BaseVRCharacterOwner)
{ {
if (BaseVRCharacterOwner->VRReplicateCapsuleHeight && MoveDataVR->CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(MoveDataVR->CapsuleHeight, VRRootCapsule->GetUnscaledCapsuleHalfHeight())) if (BaseVRCharacterOwner->GetVRReplicateCapsuleHeight() && MoveDataVR->CapsuleHeight > 0.0f && !FMath::IsNearlyEqual(MoveDataVR->CapsuleHeight, VRRootCapsule->GetUnscaledCapsuleHalfHeight()))
{ {
BaseVRCharacterOwner->SetCharacterHalfHeightVR(MoveDataVR->CapsuleHeight, false); BaseVRCharacterOwner->SetCharacterHalfHeightVR(MoveDataVR->CapsuleHeight, false);
// BaseChar->ReplicatedCapsuleHeight.CapsuleHeight = LFDiff.Z; // BaseChar->ReplicatedCapsuleHeight.CapsuleHeight = LFDiff.Z;
@ -896,6 +900,9 @@ void UVRCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iteration
bool bTriedLedgeMove = false; bool bTriedLedgeMove = false;
float remainingTime = deltaTime; float remainingTime = deltaTime;
const EMovementMode StartingMovementMode = MovementMode;
const uint8 StartingCustomMovementMode = CustomMovementMode;
// Rewind the players position by the new capsule location // Rewind the players position by the new capsule location
RewindVRRelativeMovement(); RewindVRRelativeMovement();
@ -937,9 +944,9 @@ void UVRCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iteration
devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysWalking: Velocity contains NaN after Root Motion application (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString())); devCodeVR(ensureMsgf(!Velocity.ContainsNaN(), TEXT("PhysWalking: Velocity contains NaN after Root Motion application (%s)\n%s"), *GetPathNameSafe(this), *Velocity.ToString()));
if (IsFalling()) if (MovementMode != StartingMovementMode || CustomMovementMode != StartingCustomMovementMode)
{ {
// Root motion could have put us into Falling. // Root motion could have taken us out of our current mode
// No movement has taken place this movement tick so we pass on full time/past iteration count // No movement has taken place this movement tick so we pass on full time/past iteration count
StartNewPhysics(remainingTime + timeTick, Iterations - 1); StartNewPhysics(remainingTime + timeTick, Iterations - 1);
return; return;
@ -980,9 +987,15 @@ void UVRCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iteration
// try to move forward // try to move forward
MoveAlongFloor(MoveVelocity, timeTick, &StepDownResult); MoveAlongFloor(MoveVelocity, timeTick, &StepDownResult);
if (IsFalling()) if (IsSwimming()) //just entered water
{ {
// pawn decided to jump up StartSwimming(OldLocation, OldVelocity, timeTick, remainingTime, Iterations);
return;
}
else if (MovementMode != StartingMovementMode || CustomMovementMode != StartingCustomMovementMode)
{
// pawn ended up in a different mode, probably due to the step-up-and-over flow
// let's refund the estimated unused time (if any) and keep moving in the new mode
const float DesiredDist = Delta.Size(); const float DesiredDist = Delta.Size();
if (DesiredDist > UE_KINDA_SMALL_NUMBER) if (DesiredDist > UE_KINDA_SMALL_NUMBER)
{ {
@ -993,12 +1006,6 @@ void UVRCharacterMovementComponent::PhysWalking(float deltaTime, int32 Iteration
StartNewPhysics(remainingTime, Iterations); StartNewPhysics(remainingTime, Iterations);
return; return;
} }
else if (IsSwimming()) //just entered water
{
RestorePreAdditiveVRMotionVelocity();
StartSwimmingVR(OldCapsuleLocation, OldVelocity, timeTick, remainingTime, Iterations);
return;
}
} }
// Update floor. // Update floor.
@ -1296,8 +1303,7 @@ void UVRCharacterMovementComponent::ReplicateMoveToServer(float DeltaTime, const
// Remove pending move from move list. It would have to be the last move on the list. // Remove pending move from move list. It would have to be the last move on the list.
if (ClientData->SavedMoves.Num() > 0 && ClientData->SavedMoves.Last() == ClientData->PendingMove) if (ClientData->SavedMoves.Num() > 0 && ClientData->SavedMoves.Last() == ClientData->PendingMove)
{ {
const bool bAllowShrinking = false; ClientData->SavedMoves.Pop(EAllowShrinking::No);
ClientData->SavedMoves.Pop(bAllowShrinking);
} }
ClientData->FreeMove(ClientData->PendingMove); ClientData->FreeMove(ClientData->PendingMove);
ClientData->PendingMove = nullptr; ClientData->PendingMove = nullptr;
@ -2293,6 +2299,17 @@ void UVRCharacterMovementComponent::UpdateBasedMovement(float DeltaSeconds)
} }
else else
{ {
// Set MovementBase's root actor as ignored when moving the character primitive component,
// only perform if bDeferUpdateBasedMovement is true since this means the MovementBase is simulating physics
const bool bIgnoreBaseActor = bDeferUpdateBasedMovement && bBasedMovementIgnorePhysicsBase;
AActor* MovementBaseRootActor = nullptr;
if (bIgnoreBaseActor)
{
MovementBaseRootActor = MovementBase->GetAttachmentRootActor();
UpdatedPrimitive->IgnoreActorWhenMoving(MovementBaseRootActor, true);
MoveComponentFlags |= MOVECOMP_CheckBlockingRootActorInIgnoreList; // Hit actors during MoveUpdatedComponent will have their root actor compared with the ignored actors array
}
// hack - transforms between local and world space introducing slight error FIXMESTEVE - discuss with engine team: just skip the transforms if no rotation? // hack - transforms between local and world space introducing slight error FIXMESTEVE - discuss with engine team: just skip the transforms if no rotation?
FVector BaseMoveDelta = NewBaseLocation - OldBaseLocation; FVector BaseMoveDelta = NewBaseLocation - OldBaseLocation;
if (!bRotationChanged && (BaseMoveDelta.X == 0.f) && (BaseMoveDelta.Y == 0.f)) if (!bRotationChanged && (BaseMoveDelta.X == 0.f) && (BaseMoveDelta.Y == 0.f))
@ -2304,10 +2321,18 @@ void UVRCharacterMovementComponent::UpdateBasedMovement(float DeltaSeconds)
FHitResult MoveOnBaseHit(1.f); FHitResult MoveOnBaseHit(1.f);
const FVector OldLocation = UpdatedComponent->GetComponentLocation(); const FVector OldLocation = UpdatedComponent->GetComponentLocation();
MoveUpdatedComponent(DeltaPosition, FinalQuat, true, &MoveOnBaseHit); MoveUpdatedComponent(DeltaPosition, FinalQuat, true, &MoveOnBaseHit);
if ((UpdatedComponent->GetComponentLocation() - (OldLocation + DeltaPosition)).IsNearlyZero() == false) if ((UpdatedComponent->GetComponentLocation() - (OldLocation + DeltaPosition)).IsNearlyZero() == false)
{ {
OnUnableToFollowBaseMove(DeltaPosition, OldLocation, MoveOnBaseHit); OnUnableToFollowBaseMove(DeltaPosition, OldLocation, MoveOnBaseHit);
} }
// Reset base actor ignore state
if (bIgnoreBaseActor)
{
MoveComponentFlags &= ~MOVECOMP_CheckBlockingRootActorInIgnoreList;
UpdatedPrimitive->IgnoreActorWhenMoving(MovementBaseRootActor, false);
}
} }
if (MovementBase->IsSimulatingPhysics() && CharacterOwner->GetMesh()) if (MovementBase->IsSimulatingPhysics() && CharacterOwner->GetMesh())
@ -2315,6 +2340,27 @@ void UVRCharacterMovementComponent::UpdateBasedMovement(float DeltaSeconds)
CharacterOwner->GetMesh()->ApplyDeltaToAllPhysicsTransforms(DeltaPosition, DeltaQuat); CharacterOwner->GetMesh()->ApplyDeltaToAllPhysicsTransforms(DeltaPosition, DeltaQuat);
} }
} }
// Check if falling above current base
if (IsFalling() && bStayBasedInAir)
{
FVector PawnLocation = UpdatedComponent->GetComponentLocation();
if (VRRootCapsule)
PawnLocation = VRRootCapsule->OffsetComponentToWorld.GetLocation();
FFindFloorResult OutFloorResult;
ComputeFloorDist(PawnLocation, StayBasedInAirHeight, StayBasedInAirHeight, OutFloorResult, CharacterOwner->GetCapsuleComponent()->GetScaledCapsuleRadius(), NULL);
UPrimitiveComponent* HitComponent = OutFloorResult.HitResult.Component.Get();
if (!HitComponent || HitComponent->GetAttachmentRoot() != MovementBase->GetAttachmentRoot())
{
// New or no base under the character
ApplyImpartedMovementBaseVelocity();
SetBase(NULL);
return;
}
}
} }
FVector UVRCharacterMovementComponent::GetImpartedMovementBaseVelocity() const FVector UVRCharacterMovementComponent::GetImpartedMovementBaseVelocity() const
@ -3119,6 +3165,9 @@ void UVRCharacterMovementComponent::PhysNavWalking(float deltaTime, int32 Iterat
return; return;
} }
const EMovementMode StartingMovementMode = MovementMode;
const uint8 StartingCustomMovementMode = CustomMovementMode;
// Rewind the players position by the new capsule location // Rewind the players position by the new capsule location
RewindVRRelativeMovement(); RewindVRRelativeMovement();
@ -3140,12 +3189,12 @@ void UVRCharacterMovementComponent::PhysNavWalking(float deltaTime, int32 Iterat
ApplyRootMotionToVelocity(deltaTime); ApplyRootMotionToVelocity(deltaTime);
ApplyVRMotionToVelocity(deltaTime); ApplyVRMotionToVelocity(deltaTime);
/*if (IsFalling()) if (MovementMode != StartingMovementMode || CustomMovementMode != StartingCustomMovementMode)
{ {
// Root motion could have put us into Falling // Root motion could have taken us out of our current mode
StartNewPhysics(deltaTime, Iterations); StartNewPhysics(deltaTime, Iterations);
return; return;
}*/ }
Iterations++; Iterations++;
@ -4387,6 +4436,14 @@ void UVRCharacterMovementComponent::ServerMoveHandleClientErrorVR(float ClientTi
bCanTrustClientOnLanding = false; bCanTrustClientOnLanding = false;
} }
// They have it private....
// Check for lift-off, going from walking to falling.
// Note that if bStayBasedInAir is enabled we can't rely on the walking to falling transition, instead run logic on the first tick after clearing the MovementBase
//const bool bCanLiftOffFromBase = bStayBasedInAir
// ? !MovementBase && LastServerMovementBase.Get() // If we keep the base while in air, consider lift-off if base gets set to null and we had a base last tick
// : bLastServerIsWalking; // If walking last tick, we were can consider lift-off logic
//if (bServerIsFalling && bCanLiftOffFromBase && !bTeleportedSinceLastUpdate)
if (bServerIsFalling && bLastServerIsWalking && !bTeleportedSinceLastUpdate) if (bServerIsFalling && bLastServerIsWalking && !bTeleportedSinceLastUpdate)
{ {
float ClientForwardFactor = 1.f; float ClientForwardFactor = 1.f;
@ -4686,6 +4743,9 @@ bool UVRCharacterMovementComponent::ClientUpdatePositionAfterServerUpdate()
CharacterOwner->bClientUpdating = true; CharacterOwner->bClientUpdating = true;
bForceNextFloorCheck = true; bForceNextFloorCheck = true;
// Scope these, they nest with Outer references so it should work fine, this keeps the update rotation and move autonomous from double updating the char
//const FScopedPreventAttachedComponentMove PreventMeshMove(BaseVRCharacterOwner ? BaseVRCharacterOwner->NetSmoother : nullptr);
// Store out our custom properties to restore after replaying // Store out our custom properties to restore after replaying
const FVRMoveActionArray Orig_MoveActions = MoveActionArray; const FVRMoveActionArray Orig_MoveActions = MoveActionArray;
const FVector Orig_CustomInput = CustomVRInputVector; const FVector Orig_CustomInput = CustomVRInputVector;

View file

@ -2,6 +2,8 @@
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRGestureComponent) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRGestureComponent)
#include "VRBaseCharacter.h" #include "VRBaseCharacter.h"
#include "Engine/Engine.h"
#include "Engine/World.h"
#include "Components/SplineMeshComponent.h" #include "Components/SplineMeshComponent.h"
#include "Components/SplineComponent.h" #include "Components/SplineComponent.h"
#include "Components/LineBatchComponent.h" #include "Components/LineBatchComponent.h"
@ -22,7 +24,6 @@ UVRGestureComponent::UVRGestureComponent(const FObjectInitializer& ObjectInitial
maxSlope = 3;// INT_MAX; maxSlope = 3;// INT_MAX;
//globalThreshold = 10.0f; //globalThreshold = 10.0f;
SameSampleTolerance = 0.1f; SameSampleTolerance = 0.1f;
bGestureChanged = false;
MirroringHand = EVRGestureMirrorMode::GES_NoMirror; MirroringHand = EVRGestureMirrorMode::GES_NoMirror;
bDrawSplinesCurved = true; bDrawSplinesCurved = true;
bGetGestureInWorldSpace = true; bGetGestureInWorldSpace = true;
@ -124,14 +125,14 @@ void UGesturesDatabase::FillSplineWithGesture(FVRGesture &Gesture, USplineCompon
} }
void UVRGestureComponent::BeginRecording(bool bRunDetection, bool bFlattenGesture, bool bDrawGesture, bool bDrawAsSpline, int SamplingHTZ, int SampleBufferSize, float ClampingTolerance) void UVRGestureComponent::BeginRecording(bool bRunDetection, EVRGestureFlattenAxis FlattenAxis, bool bDrawGesture, bool bDrawAsSpline, int SamplingHTZ, int SampleBufferSize, float ClampingTolerance)
{ {
RecordingBufferSize = SampleBufferSize; RecordingBufferSize = SampleBufferSize;
RecordingDelta = 1.0f / SamplingHTZ; RecordingDelta = 1.0f / SamplingHTZ;
RecordingClampingTolerance = ClampingTolerance; RecordingClampingTolerance = ClampingTolerance;
bDrawRecordingGesture = bDrawGesture; bDrawRecordingGesture = bDrawGesture;
bDrawRecordingGestureAsSpline = bDrawAsSpline; bDrawRecordingGestureAsSpline = bDrawAsSpline;
bRecordingFlattenGesture = bFlattenGesture; RecordingFlattenAxis = FlattenAxis;
GestureLog.GestureSize.Init(); GestureLog.GestureSize.Init();
// Reset does the reserve already // Reset does the reserve already
@ -221,8 +222,13 @@ void UVRGestureComponent::CaptureGestureFrame()
if (CurrentState == EVRGestureState::GES_Recording) if (CurrentState == EVRGestureState::GES_Recording)
{ {
if (bRecordingFlattenGesture) switch (RecordingFlattenAxis)
NewSample.X = 0; {
case EVRGestureFlattenAxis::GES_FlattenX: {NewSample.X = 0.0; }break;
case EVRGestureFlattenAxis::GES_FlattenY: {NewSample.Y = 0.0; }break;
case EVRGestureFlattenAxis::GES_FlattenZ: {NewSample.Z = 0.0; }break;
default: {}break;
}
if (RecordingClampingTolerance > 0.0f) if (RecordingClampingTolerance > 0.0f)
{ {

View file

@ -3,6 +3,8 @@
#include "VRPathFollowingComponent.h" #include "VRPathFollowingComponent.h"
#include UE_INLINE_GENERATED_CPP_BY_NAME(VRPathFollowingComponent) #include UE_INLINE_GENERATED_CPP_BY_NAME(VRPathFollowingComponent)
#include "CoreMinimal.h"
#include "Engine/World.h"
//#include "Runtime/Engine/Private/EnginePrivate.h" //#include "Runtime/Engine/Private/EnginePrivate.h"
//#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 13 //#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 13
@ -254,8 +256,16 @@ void UVRPathFollowingComponent::UpdatePathSegment()
{ {
const FVector AgentLocation = DestinationAgent ? DestinationAgent->GetNavAgentLocation() : DestinationActor->GetActorLocation(); const FVector AgentLocation = DestinationAgent ? DestinationAgent->GetNavAgentLocation() : DestinationActor->GetActorLocation();
// note that the condition below requires GoalLocation to be in world space. // note that the condition below requires GoalLocation to be in world space.
const FVector GoalLocation = FQuatRotationTranslationMatrix(DestinationActor->GetActorQuat(), AgentLocation).TransformPosition(MoveOffset); FVector GoalLocation = FQuatRotationTranslationMatrix(DestinationActor->GetActorQuat(), AgentLocation).TransformPosition(MoveOffset);
if (bMoveToGoalClampedToNavigation && NavigationFilter)
{
FVector HitLocation;
if (MyNavData->Raycast(CurrentLocation, GoalLocation, HitLocation, NavigationFilter))
{
GoalLocation = HitLocation;
}
}
CurrentDestination.Set(NULL, GoalLocation); CurrentDestination.Set(NULL, GoalLocation);
//UE_VLOG(this, LogPathFollowing, Log, TEXT("Moving directly to move goal rather than following last path segment")); //UE_VLOG(this, LogPathFollowing, Log, TEXT("Moving directly to move goal rather than following last path segment"));
@ -361,6 +371,27 @@ bool UVRPathFollowingComponent::HasReachedCurrentTarget(const FVector& CurrentLo
return false; return false;
} }
// If the next segment is a link with a custom reach condition, we need to call the HasReachedLinkStart on the link interface.
if (bMoveSegmentIsUsingCustomLinkReachCondition)
{
if (const INavLinkCustomInterface* MoveSegmentCustomLink = Cast<const INavLinkCustomInterface>(MoveSegmentCustomLinkOb.Get()))
{
if (ensureMsgf(Path.IsValid(), TEXT("%hs: Path should be valid when we get here. Owner [%s]."), __FUNCTION__, *GetNameSafe(GetOwner())))
{
const FNavPathPoint& LinkStart = Path->GetPathPoints()[MoveSegmentEndIndex];
if (Path->GetPathPoints().IsValidIndex(MoveSegmentEndIndex + 1))
{
const FNavPathPoint& LinkEnd = Path->GetPathPoints()[MoveSegmentEndIndex + 1];
return MoveSegmentCustomLink->HasReachedLinkStart(this, CurrentLocation, LinkStart, LinkEnd);
}
else
{
UE_LOG(LogPathFollowing, Error, TEXT("%hs: NavLink has a start, but no end. Custom reach condition won't be called. NavLinkID [%llu] - LinkStartPos [%s] - Owner [%s]"), __FUNCTION__, LinkStart.CustomNavLinkId.GetId(), *LinkStart.Location.ToString(), *GetNameSafe(GetOwner()));
}
}
}
}
const FVector CurrentTarget = GetCurrentTargetLocation(); const FVector CurrentTarget = GetCurrentTargetLocation();
const FVector CurrentDirection = GetCurrentDirection(); const FVector CurrentDirection = GetCurrentDirection();

View file

@ -27,24 +27,6 @@ void AVRPlayerController::SpawnPlayerCameraManager()
PlayerCameraManager->bUseClientSideCameraUpdates = false; PlayerCameraManager->bUseClientSideCameraUpdates = false;
} }
// #TODO 4.20: This was removed
/*void AVRPlayerController::InitNavigationControl(UPathFollowingComponent*& PathFollowingComp)
{
PathFollowingComp = FindComponentByClass<UPathFollowingComponent>();
if (PathFollowingComp == NULL)
{
PathFollowingComp = NewObject<UVRPathFollowingComponent>(this);
PathFollowingComp->RegisterComponentWithWorld(GetWorld());
PathFollowingComp->Initialize();
}
}*/
/*IPathFollowingAgentInterface* AVRPlayerController::GetPathFollowingAgent() const
{
// Moved spawning the path following component into the path finding logic instead
return FNavigationSystem::FindPathFollowingAgentForActor(*this);
}*/
void AVRPlayerController::PlayerTick(float DeltaTime) void AVRPlayerController::PlayerTick(float DeltaTime)
{ {

View file

@ -6,6 +6,8 @@
//#include "Runtime/Engine/Private/EnginePrivate.h" //#include "Runtime/Engine/Private/EnginePrivate.h"
//#include "WorldCollision.h" //#include "WorldCollision.h"
#include "PhysicsPublic.h" #include "PhysicsPublic.h"
#include "Engine/World.h"
#include "Engine/Engine.h"
#include "Engine/ScopedMovementUpdate.h" #include "Engine/ScopedMovementUpdate.h"
#include "SceneManagement.h" #include "SceneManagement.h"
#include "PrimitiveSceneProxy.h" #include "PrimitiveSceneProxy.h"
@ -13,7 +15,9 @@
#include "IHeadMountedDisplay.h" #include "IHeadMountedDisplay.h"
#include "IXRTrackingSystem.h" #include "IXRTrackingSystem.h"
#include "VRCharacter.h" #include "VRCharacter.h"
#include "Engine/OverlapResult.h"
#include "Algo/Copy.h" #include "Algo/Copy.h"
#include "AI/Navigation/NavigationRelevantData.h"
#include "Components/PrimitiveComponent.h" #include "Components/PrimitiveComponent.h"
@ -310,6 +314,7 @@ UVRRootComponent::UVRRootComponent(const FObjectInitializer& ObjectInitializer)
SetCanEverAffectNavigation(false); SetCanEverAffectNavigation(false);
bDynamicObstacle = true; bDynamicObstacle = true;
LineThickness = 1.25f;
//bOffsetByHMD = false; //bOffsetByHMD = false;
} }
@ -333,6 +338,7 @@ public:
, bSimulating(false) , bSimulating(false)
//, OffsetComponentToWorld(InComponent->OffsetComponentToWorld) //, OffsetComponentToWorld(InComponent->OffsetComponentToWorld)
, LocalToWorld(InComponent->OffsetComponentToWorld.ToMatrixWithScale()) , LocalToWorld(InComponent->OffsetComponentToWorld.ToMatrixWithScale())
, LineThickness(InComponent->GetLineThickness())
{ {
bWillEverBeLit = false; bWillEverBeLit = false;
} }
@ -357,14 +363,14 @@ public:
// If in editor views, lets offset the capsule upwards so that it views correctly // If in editor views, lets offset the capsule upwards so that it views correctly
if (bSimulating) if (bSimulating)
{ {
DrawWireCapsule(PDI, LocalToWorld.GetOrigin() - FVector(0.f, 0.f, CapsuleHalfHeight), LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World); DrawWireCapsule(PDI, LocalToWorld.GetOrigin() - FVector(0.f, 0.f, CapsuleHalfHeight), LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, LineThickness);
} }
else if (UseEditorCompositing(View)) else if (UseEditorCompositing(View))
{ {
DrawWireCapsule(PDI, LocalToWorld.GetOrigin() /*+ FVector(0.f, 0.f, CapsuleHalfHeight)*/, LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, 1.25f); DrawWireCapsule(PDI, LocalToWorld.GetOrigin() /*+ FVector(0.f, 0.f, CapsuleHalfHeight)*/, LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, LineThickness);
} }
else else
DrawWireCapsule(PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, 1.25f); DrawWireCapsule(PDI, LocalToWorld.GetOrigin(), LocalToWorld.GetUnitAxis(EAxis::X), LocalToWorld.GetUnitAxis(EAxis::Y), LocalToWorld.GetUnitAxis(EAxis::Z), DrawCapsuleColor, CapsuleRadius, CapsuleHalfHeight, CapsuleSides, SDPG_World, LineThickness);
} }
} }
} }
@ -405,6 +411,7 @@ private:
bool bSimulating = false; bool bSimulating = false;
//FTransform OffsetComponentToWorld; //FTransform OffsetComponentToWorld;
FMatrix LocalToWorld; FMatrix LocalToWorld;
const float LineThickness;
}; };
FPrimitiveSceneProxy* UVRRootComponent::CreateSceneProxy() FPrimitiveSceneProxy* UVRRootComponent::CreateSceneProxy()
@ -547,9 +554,10 @@ void UVRRootComponent::TickComponent(float DeltaTime, enum ELevelTick TickType,
if (bRetainRoomscale) if (bRetainRoomscale)
{ {
// Pre-Process this for network sends // Pre-Process this for network sends
curCameraLoc.X = FMath::RoundToFloat(curCameraLoc.X * 100.f) / 100.f; UE::Net::QuantizeVector(100, curCameraLoc);
curCameraLoc.Y = FMath::RoundToFloat(curCameraLoc.Y * 100.f) / 100.f; //curCameraLoc.X = FMath::RoundToFloat(curCameraLoc.X * 100.f) / 100.f;
curCameraLoc.Z = FMath::RoundToFloat(curCameraLoc.Z * 100.f) / 100.f; //curCameraLoc.Y = FMath::RoundToFloat(curCameraLoc.Y * 100.f) / 100.f;
//curCameraLoc.Z = FMath::RoundToFloat(curCameraLoc.Z * 100.f) / 100.f;
} }
@ -622,9 +630,10 @@ void UVRRootComponent::TickComponent(float DeltaTime, enum ELevelTick TickType,
lastCameraRot = curCameraRot; lastCameraRot = curCameraRot;
//DifferenceFromLastFrame = (NextTransform.GetLocation() - LastPosition);// .GetSafeNormal2D(); //DifferenceFromLastFrame = (NextTransform.GetLocation() - LastPosition);// .GetSafeNormal2D();
DifferenceFromLastFrame.X = FMath::RoundToFloat(DifferenceFromLastFrame.X * 100.f) / 100.f; UE::Net::QuantizeVector(100, DifferenceFromLastFrame);
DifferenceFromLastFrame.Y = FMath::RoundToFloat(DifferenceFromLastFrame.Y * 100.f) / 100.f; //DifferenceFromLastFrame.X = FMath::RoundToFloat(DifferenceFromLastFrame.X * 100.f) / 100.f;
DifferenceFromLastFrame.Z = FMath::RoundToFloat(DifferenceFromLastFrame.Z * 100.f) / 100.f; //DifferenceFromLastFrame.Y = FMath::RoundToFloat(DifferenceFromLastFrame.Y * 100.f) / 100.f;
//DifferenceFromLastFrame.Z = FMath::RoundToFloat(DifferenceFromLastFrame.Z * 100.f) / 100.f;
//DifferenceFromLastFrame.Z = 0.0f; // Reset Z to zero, its not used anyway and this lets me reuse the Z component for capsule half height //DifferenceFromLastFrame.Z = 0.0f; // Reset Z to zero, its not used anyway and this lets me reuse the Z component for capsule half height
} }
else else
@ -648,9 +657,13 @@ void UVRRootComponent::TickComponent(float DeltaTime, enum ELevelTick TickType,
{ {
// I'm limiting it to a -100 - 100 unit range in case people somehow skip tracking so far that this multiplication // I'm limiting it to a -100 - 100 unit range in case people somehow skip tracking so far that this multiplication
// Would overflow the max/min values of a float. It shouldn't ever be harmful as that is a loooot of travel in one tick // Would overflow the max/min values of a float. It shouldn't ever be harmful as that is a loooot of travel in one tick
DifferenceFromLastFrame.X = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.X, -100.0f, 100.0f) * 10000.f) / 10000.f; DifferenceFromLastFrame.X = FMath::Clamp(DifferenceFromLastFrame.X, -100.0f, 100.0f);
DifferenceFromLastFrame.Y = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.Y, -100.0f, 100.0f) * 10000.f) / 10000.f; DifferenceFromLastFrame.Y = FMath::Clamp(DifferenceFromLastFrame.Y, -100.0f, 100.0f);
DifferenceFromLastFrame.Z = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.Z, -100.0f, 100.0f) * 10000.f) / 10000.f; DifferenceFromLastFrame.Z = FMath::Clamp(DifferenceFromLastFrame.Z, -100.0f, 100.0f);
UE::Net::QuantizeVector(10000, DifferenceFromLastFrame);
//DifferenceFromLastFrame.X = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.X, -100.0f, 100.0f) * 10000.f) / 10000.f;
//DifferenceFromLastFrame.Y = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.Y, -100.0f, 100.0f) * 10000.f) / 10000.f;
//DifferenceFromLastFrame.Z = FMath::RoundToFloat(FMath::Clamp(DifferenceFromLastFrame.Z, -100.0f, 100.0f) * 10000.f) / 10000.f;
//DifferenceFromLastFrame.Z = 0.0f; // Reset Z to zero, its not used anyway and this lets me reuse the Z component for capsule half height //DifferenceFromLastFrame.Z = 0.0f; // Reset Z to zero, its not used anyway and this lets me reuse the Z component for capsule half height
} }
} }
@ -1060,7 +1073,7 @@ bool UVRRootComponent::MoveComponentImpl(const FVector& Delta, const FQuat& NewR
if (TestHit.bBlockingHit) if (TestHit.bBlockingHit)
{ {
if (!ShouldIgnoreHitResult(MyWorld, bAllowSimulatingCollision, TestHit, Delta, Actor, MoveFlags)) if (!ShouldIgnoreHitResult(MyWorld, bAllowSimulatingCollision, TestHit, Delta, Actor, MoveFlags) && !ShouldComponentIgnoreHitResult(TestHit, MoveFlags))
{ {
if (TestHit.bStartPenetrating) if (TestHit.bStartPenetrating)
{ {
@ -1136,8 +1149,7 @@ bool UVRRootComponent::MoveComponentImpl(const FVector& Delta, const FQuat& NewR
// Remove any pending overlaps after this point, we are not going as far as we swept. // Remove any pending overlaps after this point, we are not going as far as we swept.
if (FirstNonInitialOverlapIdx != INDEX_NONE) if (FirstNonInitialOverlapIdx != INDEX_NONE)
{ {
const bool bAllowShrinking = false; PendingOverlaps.SetNum(FirstNonInitialOverlapIdx, EAllowShrinking::No);
PendingOverlaps.SetNum(FirstNonInitialOverlapIdx, bAllowShrinking);
} }
} }
} }
@ -1376,14 +1388,13 @@ bool UVRRootComponent::UpdateOverlapsImpl(const TOverlapArrayView* NewPendingOve
for (int32 CompIdx = 0; CompIdx < OldOverlappingComponentPtrs.Num() && NewOverlappingComponentPtrs.Num() > 0; ++CompIdx) for (int32 CompIdx = 0; CompIdx < OldOverlappingComponentPtrs.Num() && NewOverlappingComponentPtrs.Num() > 0; ++CompIdx)
{ {
// RemoveAtSwap is ok, since it is not necessary to maintain order // RemoveAtSwap is ok, since it is not necessary to maintain order
const bool bAllowShrinking = false;
const FOverlapInfo* SearchItem = OldOverlappingComponentPtrs[CompIdx]; const FOverlapInfo* SearchItem = OldOverlappingComponentPtrs[CompIdx];
const int32 NewElementIdx = IndexOfOverlapFast(NewOverlappingComponentPtrs, SearchItem); const int32 NewElementIdx = IndexOfOverlapFast(NewOverlappingComponentPtrs, SearchItem);
if (NewElementIdx != INDEX_NONE) if (NewElementIdx != INDEX_NONE)
{ {
NewOverlappingComponentPtrs.RemoveAtSwap(NewElementIdx, 1, bAllowShrinking); NewOverlappingComponentPtrs.RemoveAtSwap(NewElementIdx, 1, EAllowShrinking::No);
OldOverlappingComponentPtrs.RemoveAtSwap(CompIdx, 1, bAllowShrinking); OldOverlappingComponentPtrs.RemoveAtSwap(CompIdx, 1, EAllowShrinking::No);
--CompIdx; --CompIdx;
} }
} }
@ -1413,7 +1424,7 @@ bool UVRRootComponent::UpdateOverlapsImpl(const TOverlapArrayView* NewPendingOve
const int32 StaleElementIndex = IndexOfOverlapFast(OverlappingComponents, OtherOverlap); const int32 StaleElementIndex = IndexOfOverlapFast(OverlappingComponents, OtherOverlap);
if (StaleElementIndex != INDEX_NONE) if (StaleElementIndex != INDEX_NONE)
{ {
OverlappingComponents.RemoveAtSwap(StaleElementIndex, 1, bAllowShrinking); OverlappingComponents.RemoveAtSwap(StaleElementIndex, 1, bAllowShrinking ? EAllowShrinking::Yes : EAllowShrinking::No);
} }
} }
} }
@ -1515,7 +1526,7 @@ bool UVRRootComponent::IsLocallyControlled() const
{ {
if (GetNetMode() < ENetMode::NM_Client) if (GetNetMode() < ENetMode::NM_Client)
{ {
if (owningVRChar->VRReplicateCapsuleHeight) if (owningVRChar->GetVRReplicateCapsuleHeight())
{ {
owningVRChar->ReplicatedCapsuleHeight.CapsuleHeight = CapsuleHalfHeight; owningVRChar->ReplicatedCapsuleHeight.CapsuleHeight = CapsuleHalfHeight;
} }
@ -1649,7 +1660,7 @@ bool UVRRootComponent::ConvertSweptOverlapsToCurrentOverlapsVR(
// Not handled yet. We could do it by checking every body explicitly and track each body index in the overlap test, but this seems like a rare need. // Not handled yet. We could do it by checking every body explicitly and track each body index in the overlap test, but this seems like a rare need.
return false; return false;
} }
else if (Cast<USkeletalMeshComponent>(OtherPrimitive) || Cast<USkeletalMeshComponent>(this)) else if (Cast<USkeletalMeshComponent>(OtherPrimitive) /* || Cast<USkeletalMeshComponent>(this)*/)
{ {
// SkeletalMeshComponent does not support this operation, and would return false in the test when an actual query could return true. // SkeletalMeshComponent does not support this operation, and would return false in the test when an actual query could return true.
return false; return false;

View file

@ -17,6 +17,7 @@
#include "IStereoLayers.h" #include "IStereoLayers.h"
#include "IHeadMountedDisplay.h" #include "IHeadMountedDisplay.h"
#include "PrimitiveViewRelevance.h" #include "PrimitiveViewRelevance.h"
#include "StereoLayerAdditionalFlagsManager.h"
#include "PrimitiveSceneProxy.h" #include "PrimitiveSceneProxy.h"
#include "UObject/ConstructorHelpers.h" #include "UObject/ConstructorHelpers.h"
#include "EngineGlobals.h" #include "EngineGlobals.h"
@ -346,7 +347,6 @@ void UVRStereoWidgetRenderComponent::RenderWidget(float DeltaTime)
const EPixelFormat requestedFormat = FSlateApplication::Get().GetRenderer()->GetSlateRecommendedColorFormat(); const EPixelFormat requestedFormat = FSlateApplication::Get().GetRenderer()->GetSlateRecommendedColorFormat();
RenderTarget = NewObject<UTextureRenderTarget2D>(); RenderTarget = NewObject<UTextureRenderTarget2D>();
check(RenderTarget); check(RenderTarget);
RenderTarget->AddToRoot();
RenderTarget->ClearColor = RenderTargetClearColor; RenderTarget->ClearColor = RenderTargetClearColor;
RenderTarget->TargetGamma = WidgetRenderGamma; RenderTarget->TargetGamma = WidgetRenderGamma;
RenderTarget->InitCustomFormat(TextureSize.X, TextureSize.Y, requestedFormat /*PF_B8G8R8A8*/, false); RenderTarget->InitCustomFormat(TextureSize.X, TextureSize.Y, requestedFormat /*PF_B8G8R8A8*/, false);
@ -385,9 +385,9 @@ UVRStereoWidgetComponent::UVRStereoWidgetComponent(const FObjectInitializer& Obj
//, StereoLayerType(SLT_TrackerLocked) //, StereoLayerType(SLT_TrackerLocked)
//, StereoLayerShape(SLSH_QuadLayer) //, StereoLayerShape(SLSH_QuadLayer)
, Priority(0) , Priority(0)
, LayerId(IStereoLayers::FLayerDesc::INVALID_LAYER_ID)
, bIsDirty(true) , bIsDirty(true)
, bTextureNeedsUpdate(false) , bTextureNeedsUpdate(false)
, LayerId(IStereoLayers::FLayerDesc::INVALID_LAYER_ID)
, LastTransform(FTransform::Identity) , LastTransform(FTransform::Identity)
, bLastVisible(false) , bLastVisible(false)
{ {
@ -412,6 +412,16 @@ UVRStereoWidgetComponent::~UVRStereoWidgetComponent()
{ {
} }
void UVRStereoWidgetComponent::EndPlay(const EEndPlayReason::Type EndPlayReason)
{
if (EndPlayReason == EEndPlayReason::EndPlayInEditor || EndPlayReason == EEndPlayReason::Quit)
{
//FStereoLayerAdditionalFlagsManager::Destroy();
}
}
void UVRStereoWidgetComponent::BeginDestroy() void UVRStereoWidgetComponent::BeginDestroy()
{ {
IStereoLayers* StereoLayers; IStereoLayers* StereoLayers;
@ -716,6 +726,13 @@ void UVRStereoWidgetComponent::TickComponent(float DeltaTime, enum ELevelTick Ti
LayerDsec.Flags |= (bSupportsDepth) ? IStereoLayers::LAYER_FLAG_SUPPORT_DEPTH : 0; LayerDsec.Flags |= (bSupportsDepth) ? IStereoLayers::LAYER_FLAG_SUPPORT_DEPTH : 0;
LayerDsec.Flags |= (!bCurrVisible) ? IStereoLayers::LAYER_FLAG_HIDDEN : 0; LayerDsec.Flags |= (!bCurrVisible) ? IStereoLayers::LAYER_FLAG_HIDDEN : 0;
// Would love to implement but they aren't exporting the symbols
/*TSharedPtr<FStereoLayerAdditionalFlagsManager> FlagsManager = FStereoLayerAdditionalFlagsManager::Get();
for (FName& Flag : AdditionalFlags)
{
LayerDsec.Flags |= FlagsManager->GetFlagValue(Flag);
}*/
// Fix this later when WorldLocked is no longer wrong. // Fix this later when WorldLocked is no longer wrong.
switch (Space) switch (Space)
{ {
@ -1094,7 +1111,7 @@ public:
bShadowMapped = false; bShadowMapped = false;
} }
virtual void OnTransformChanged() override virtual void OnTransformChanged(FRHICommandListBase& RHICmdList) override
{ {
Origin = GetLocalToWorld().GetOrigin(); Origin = GetLocalToWorld().GetOrigin();
} }

View file

@ -316,6 +316,10 @@ public:
~UGripMotionControllerComponent(); ~UGripMotionControllerComponent();
// TMP until physics velocity bug is fixed #TODO: Remove
void CalculateGripVelocity(FBPActorGripInformation &GripToFill, UPrimitiveComponent* ComponentToSample, float DeltaTime);
// Custom version of the component sweep function to remove that aggravating warning epic is throwing about skeletal mesh components. // Custom version of the component sweep function to remove that aggravating warning epic is throwing about skeletal mesh components.
void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
virtual void InitializeComponent() override; virtual void InitializeComponent() override;
@ -494,10 +498,17 @@ public:
UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_GrippedObjects) UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_GrippedObjects)
TArray<FBPActorGripInformation> GrippedObjects; TArray<FBPActorGripInformation> GrippedObjects;
// If modifying members in gripped objects directly or a specific grip you need to call this function if you are using Push Networking
void DIRTY_GRIPPED_OBJECTS();
// When possible I suggest that you use GetAllGrips/GetGrippedObjects instead of directly referencing this // When possible I suggest that you use GetAllGrips/GetGrippedObjects instead of directly referencing this
UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_LocallyGrippedObjects) UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_LocallyGrippedObjects)
TArray<FBPActorGripInformation> LocallyGrippedObjects; TArray<FBPActorGripInformation> LocallyGrippedObjects;
// If modifying members in locally gripped objects directly or a specific grip you need to call this function if you are using Push Networking
void DIRTY_LOCALLY_GRIPPED_OBJECTS();
// Local Grip TransactionalBuffer to store server sided grips that need to be emplaced into the local buffer // Local Grip TransactionalBuffer to store server sided grips that need to be emplaced into the local buffer
UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_LocalTransaction) UPROPERTY(BlueprintReadOnly, Replicated, Category = "GripMotionController", ReplicatedUsing = OnRep_LocalTransaction)
TArray<FBPActorGripInformation> LocalTransactionBuffer; TArray<FBPActorGripInformation> LocalTransactionBuffer;
@ -766,37 +777,8 @@ public:
return true; return true;
} }
inline void CheckTransactionBuffer() // Check the local transaction buffer
{ void CheckTransactionBuffer();
if (LocalTransactionBuffer.Num())
{
for (int i = LocalTransactionBuffer.Num() - 1; i >= 0; --i)
{
if (LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped && LocalTransactionBuffer[i].GripID != LocalTransactionBuffer[i].ValueCache.CachedGripID)
{
// There appears to be a bug with TArray replication where if you replace an index with another value of that
// Index, it doesn't fully re-init the object, this is a workaround to re-zero non replicated variables
// when that happens.
LocalTransactionBuffer[i].ClearNonReppingItems();
}
if (!LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped && LocalTransactionBuffer[i].GrippedObject->IsValidLowLevelFast())
{
LocalTransactionBuffer[i].ValueCache.bWasInitiallyRepped = true;
LocalTransactionBuffer[i].ValueCache.CachedGripID = LocalTransactionBuffer[i].GripID;
int32 Index = LocallyGrippedObjects.Add(LocalTransactionBuffer[i]);
if (Index != INDEX_NONE)
{
NotifyGrip(LocallyGrippedObjects[Index]);
}
Server_NotifyHandledTransaction(LocalTransactionBuffer[i].GripID);
}
}
}
}
UFUNCTION() UFUNCTION()
virtual void OnRep_LocalTransaction(TArray<FBPActorGripInformation> OriginalArrayState) // Original array state is useless without full serialize, it just hold last delta virtual void OnRep_LocalTransaction(TArray<FBPActorGripInformation> OriginalArrayState) // Original array state is useless without full serialize, it just hold last delta
@ -848,18 +830,29 @@ public:
// Run the smoothing step // Run the smoothing step
void RunNetworkedSmoothing(float DeltaTime); void RunNetworkedSmoothing(float DeltaTime);
protected:
// Rate to update the position to the server, 100htz is default (same as replication rate, should also hit every tick). // Rate to update the position to the server, 100htz is default (same as replication rate, should also hit every tick).
// On dedicated servers the update rate should be at or lower than the server tick rate for smoothing to work // On dedicated servers the update rate should be at or lower than the server tick rate for smoothing to work
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking", meta = (ClampMin = "0", UIMin = "0")) UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking", meta = (ClampMin = "0", UIMin = "0"))
float ControllerNetUpdateRate; float ControllerNetUpdateRate;
public:
void SetControllerNetUpdateRate(float NewControllerNetUpdateRate);
inline float GetControllerNetUpdateRate() { return ControllerNetUpdateRate; };
// Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case, also used for remotes to lerp position // Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case, also used for remotes to lerp position
float ControllerNetUpdateCount; float ControllerNetUpdateCount;
protected:
// Whether to smooth (lerp) between ticks for the replicated motion, DOES NOTHING if update rate is larger than FPS! // Whether to smooth (lerp) between ticks for the replicated motion, DOES NOTHING if update rate is larger than FPS!
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking") UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking")
bool bSmoothReplicatedMotion; bool bSmoothReplicatedMotion;
public:
void SetSmoothReplicatedMotion(bool NewSmoothReplicatedMotion);
inline bool GetSmoothReplicatedMotion() { return bSmoothReplicatedMotion; };
// If true then we will use exponential smoothing with buffered correction // If true then we will use exponential smoothing with buffered correction
UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bSmoothReplicatedMotion")) UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bSmoothReplicatedMotion"))
bool bUseExponentialSmoothing = true; bool bUseExponentialSmoothing = true;
@ -876,10 +869,16 @@ public:
UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing")) UPROPERTY(EditAnywhere, Category = "GripMotionController|Networking|Smoothing", meta = (editcondition = "bUseExponentialSmoothing"))
float NetworkNoSmoothUpdateDistance = 100.f; float NetworkNoSmoothUpdateDistance = 100.f;
protected:
// Whether to replicate even if no tracking (FPS or test characters) // Whether to replicate even if no tracking (FPS or test characters)
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking") UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "GripMotionController|Networking")
bool bReplicateWithoutTracking; bool bReplicateWithoutTracking;
public:
void SetReplicateWithoutTracking(bool NewReplicateWithoutTracking);
inline bool GetReplicateWithoutTracking() { return bReplicateWithoutTracking; };
// I'm sending it unreliable because it is being resent pretty often // I'm sending it unreliable because it is being resent pretty often
UFUNCTION(Unreliable, Server, WithValidation) UFUNCTION(Unreliable, Server, WithValidation)
void Server_SendControllerTransform(FBPVRComponentPosRep NewTransform); void Server_SendControllerTransform(FBPVRComponentPosRep NewTransform);

View file

@ -181,11 +181,8 @@ public:
virtual void OnLodgeHitCallback(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit); virtual void OnLodgeHitCallback(AActor* SelfActor, AActor* OtherActor, FVector NormalImpulse, const FHitResult& Hit);
UFUNCTION(BlueprintCallable, Category = "Weapon Settings") UFUNCTION(BlueprintCallable, Category = "Weapon Settings")
void SetIsLodged(bool IsLodged, UPrimitiveComponent * LodgeComponent) void SetIsLodged(bool IsLodged, UPrimitiveComponent* LodgeComponent);
{
bIsLodged = IsLodged;
LodgedComponent = LodgeComponent;
}
bool bIsLodged; bool bIsLodged;
TWeakObjectPtr<UPrimitiveComponent> LodgedComponent; TWeakObjectPtr<UPrimitiveComponent> LodgedComponent;

View file

@ -38,6 +38,7 @@ public:
virtual void GatherCurrentMovement() override; virtual void GatherCurrentMovement() override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -46,6 +47,13 @@ public:
// where the object will never have a replicating script // where the object will never have a replicating script
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& ObjList) override; virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& ObjList) override;
@ -78,8 +86,16 @@ public:
// Client Auth Throwing Data and functions // Client Auth Throwing Data and functions
// ------------------------------------------------ // ------------------------------------------------
protected:
// Replication settings for client auth throwing
// Must call MarkClientAuthReplicationDirty if setting the properties of it live
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
FVRClientAuthReplicationData ClientAuthReplicationData; FVRClientAuthReplicationData ClientAuthReplicationData;
public:
// If changing this in c++ it is using a getter to make sure it is dirtied
FVRClientAuthReplicationData& GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData);
// Add this to client side physics replication (until coming to rest or timeout period is hit) // Add this to client side physics replication (until coming to rest or timeout period is hit)
UFUNCTION(BlueprintCallable, Category = "Networking") UFUNCTION(BlueprintCallable, Category = "Networking")
@ -122,32 +138,31 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
protected:
// Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip. // Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip.
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
bool bAllowIgnoringAttachOnOwner; bool bAllowIgnoringAttachOnOwner;
public:
void SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner);
inline bool GetAllowIgnoringAttachOnOwner() { return bAllowIgnoringAttachOnOwner; };
// Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled) // Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled)
inline bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const /*inline*/ bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const;
{
if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client)
return false;
if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive ||
VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep)
{
return HasLocalNetOwner();
}
else
return false;
}
// Handle fixing some bugs and issues with ReplicateMovement being off // Handle fixing some bugs and issues with ReplicateMovement being off
virtual void OnRep_AttachmentReplication() override; virtual void OnRep_AttachmentReplication() override;
@ -173,11 +188,21 @@ public:
// On Destroy clean up our objects // On Destroy clean up our objects
virtual void BeginDestroy() override; virtual void BeginDestroy() override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity

View file

@ -31,6 +31,7 @@ public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -39,6 +40,13 @@ public:
// where the object will never have a replicating script // where the object will never have a replicating script
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
@ -76,10 +84,14 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
@ -94,6 +106,7 @@ public:
// This one is for components to clean up // This one is for components to clean up
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
protected:
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
@ -106,6 +119,16 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
void SetReplicateMovement(bool bNewReplicateMovement);
inline bool GetReplicateMovement() { return bReplicateMovement; };
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity

View file

@ -31,6 +31,7 @@ public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -40,6 +41,14 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
// Sets the Deny Gripping variable on the FBPInterfaceSettings struct // Sets the Deny Gripping variable on the FBPInterfaceSettings struct
@ -75,9 +84,12 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
@ -92,6 +104,8 @@ public:
// This one is for components to clean up // This one is for components to clean up
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
protected:
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
@ -105,6 +119,17 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
void SetReplicateMovement(bool bNewReplicateMovement);
inline bool GetReplicateMovement() { return bReplicateMovement; };
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity
virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override;

View file

@ -10,9 +10,9 @@
#include "PhysicsReplicationInterface.h" #include "PhysicsReplicationInterface.h"
#include "Physics/PhysicsInterfaceDeclares.h" #include "Physics/PhysicsInterfaceDeclares.h"
#include "PhysicsProxy/SingleParticlePhysicsProxyFwd.h" #include "PhysicsProxy/SingleParticlePhysicsProxyFwd.h"
#include "Chaos/Particles.h"
#include "Chaos/PhysicsObject.h" #include "Chaos/PhysicsObject.h"
#include "Chaos/SimCallbackObject.h" #include "Chaos/SimCallbackObject.h"
#include "Physics/NetworkPhysicsSettingsComponent.h"
#include "GrippablePhysicsReplication.generated.h" #include "GrippablePhysicsReplication.generated.h"
@ -33,13 +33,18 @@
//struct FAsyncPhysicsRepCallbackDataVR; //struct FAsyncPhysicsRepCallbackDataVR;
//class FPhysicsReplicationAsyncCallbackVR; //class FPhysicsReplicationAsyncCallbackVR;
#pragma region FPhysicsReplicationAsync
class FPhysicsReplicationAsyncVR : public Chaos::TSimCallbackObject< class FPhysicsReplicationAsyncVR : public Chaos::TSimCallbackObject<
FPhysicsReplicationAsyncInput, FPhysicsReplicationAsyncInput,
Chaos::FSimCallbackNoOutput, Chaos::FSimCallbackNoOutput,
Chaos::ESimCallbackOptions::Presimulate> Chaos::ESimCallbackOptions::Presimulate | Chaos::ESimCallbackOptions::PhysicsObjectUnregister>
{ {
virtual FName GetFNameForStatId() const override; virtual FName GetFNameForStatId() const override;
virtual void OnPostInitialize_Internal() override;
virtual void OnPreSimulate_Internal() override; virtual void OnPreSimulate_Internal() override;
virtual void OnPhysicsObjectUnregistered_Internal(Chaos::FConstPhysicsObjectHandle PhysicsObject) override;
virtual void ApplyTargetStatesAsync(const float DeltaSeconds, const FPhysicsRepErrorCorrectionData& ErrorCorrection, const TArray<FPhysicsRepAsyncInputData>& TargetStates); virtual void ApplyTargetStatesAsync(const float DeltaSeconds, const FPhysicsRepErrorCorrectionData& ErrorCorrection, const TArray<FPhysicsRepAsyncInputData>& TargetStates);
// Replication functions // Replication functions
@ -48,14 +53,25 @@ class FPhysicsReplicationAsyncVR : public Chaos::TSimCallbackObject<
virtual bool PredictiveInterpolation(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds); virtual bool PredictiveInterpolation(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds);
virtual bool ResimulationReplication(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds); virtual bool ResimulationReplication(Chaos::FPBDRigidParticleHandle* Handle, FReplicatedPhysicsTargetAsync& Target, const float DeltaSeconds);
public:
virtual void RegisterSettings(Chaos::FConstPhysicsObjectHandle PhysicsObject, FNetworkPhysicsSettingsAsync InSettings);
private: private:
float LatencyOneWay; float LatencyOneWay;
FRigidBodyErrorCorrection ErrorCorrectionDefault; FRigidBodyErrorCorrection ErrorCorrectionDefault;
TMap<Chaos::FPhysicsObject*, FReplicatedPhysicsTargetAsync> ObjectToTarget; FNetworkPhysicsSettingsAsync SettingsCurrent;
FNetworkPhysicsSettingsAsync SettingsDefault;
TMap<Chaos::FConstPhysicsObjectHandle, FReplicatedPhysicsTargetAsync> ObjectToTarget;
TMap<Chaos::FConstPhysicsObjectHandle, FNetworkPhysicsSettingsAsync> ObjectToSettings;
TArray<int32> ParticlesInResimIslands;
private: private:
void UpdateAsyncTarget(const FPhysicsRepAsyncInputData& Input); void UpdateAsyncTarget(const FPhysicsRepAsyncInputData& Input, Chaos::FPBDRigidsSolver* RigidsSolver);
void UpdateRewindDataTarget(const FPhysicsRepAsyncInputData& Input); void UpdateRewindDataTarget(const FPhysicsRepAsyncInputData& Input);
void CacheResimInteractions();
// Sets SettingsCurrent to either the objects custom settings or to the default settings
void FetchObjectSettings(Chaos::FConstPhysicsObjectHandle PhysicsObject);
static void ExtrapolateTarget(FReplicatedPhysicsTargetAsync& Target, const int32 ExtrapolateFrames, const float DeltaSeconds);
public: public:
void Setup(FRigidBodyErrorCorrection ErrorCorrection) void Setup(FRigidBodyErrorCorrection ErrorCorrection)
@ -64,7 +80,7 @@ public:
} }
}; };
#pragma endregion // FPhysicsReplicationAsync
class FPhysicsReplicationVR : public FPhysicsReplication class FPhysicsReplicationVR : public FPhysicsReplication
{ {
@ -81,8 +97,10 @@ public:
virtual bool ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, int32 LocalFrame, int32 NumPredictedFrames) override; virtual bool ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, int32 LocalFrame, int32 NumPredictedFrames) override;
virtual bool ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, bool* bDidHardSnap = nullptr) override; virtual bool ApplyRigidBodyState(float DeltaSeconds, FBodyInstance* BI, FReplicatedPhysicsTarget& PhysicsTarget, const FRigidBodyErrorCorrection& ErrorCorrection, const float PingSecondsOneWay, bool* bDidHardSnap = nullptr) override;
virtual void SetReplicatedTarget(UPrimitiveComponent* Component, FName BoneName, const FRigidBodyState& ReplicatedTarget, int32 ServerFrame) override; void SetReplicatedTargetVR(Chaos::FConstPhysicsObjectHandle PhysicsObject, const FRigidBodyState& ReplicatedTarget, int32 ServerFrame, EPhysicsReplicationMode ReplicationMode = EPhysicsReplicationMode::Default);
void SetReplicatedTargetVR(Chaos::FPhysicsObject* PhysicsObject, const FRigidBodyState& ReplicatedTarget, int32 ServerFrame, EPhysicsReplicationMode ReplicationMode);
virtual void RemoveReplicatedTarget(UPrimitiveComponent* Component) override;
TArray<FReplicatedPhysicsTarget> ReplicatedTargetsQueueVR; TArray<FReplicatedPhysicsTarget> ReplicatedTargetsQueueVR;
FPhysicsReplicationAsyncVR* PhysicsReplicationAsyncVR; FPhysicsReplicationAsyncVR* PhysicsReplicationAsyncVR;
@ -91,6 +109,7 @@ public:
void PrepareAsyncData_ExternalVR(const FRigidBodyErrorCorrection& ErrorCorrection); //prepare async data for writing. Call on external thread (i.e. game thread) void PrepareAsyncData_ExternalVR(const FRigidBodyErrorCorrection& ErrorCorrection); //prepare async data for writing. Call on external thread (i.e. game thread)
}; };
class IPhysicsReplicationFactoryVR : public IPhysicsReplicationFactory class IPhysicsReplicationFactoryVR : public IPhysicsReplicationFactory
{ {
public: public:

View file

@ -30,11 +30,13 @@ class VREXPANSIONPLUGIN_API UOptionalRepSkeletalMeshComponent : public USkeletal
public: public:
UOptionalRepSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer); UOptionalRepSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer);
public: protected:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
@ -64,6 +66,7 @@ public:
virtual void GatherCurrentMovement() override; virtual void GatherCurrentMovement() override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -72,6 +75,13 @@ public:
// where the object will never have a replicating script // where the object will never have a replicating script
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags) override;
virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& ObjList) override; virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& ObjList) override;
@ -104,8 +114,12 @@ public:
// Client Auth Throwing Data and functions // Client Auth Throwing Data and functions
// ------------------------------------------------ // ------------------------------------------------
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
FVRClientAuthReplicationData ClientAuthReplicationData; FVRClientAuthReplicationData ClientAuthReplicationData;
public:
// If changing this in c++ it is using a getter to make sure it is dirtied
FVRClientAuthReplicationData& GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData);
// Add this to client side physics replication (until coming to rest or timeout period is hit) // Add this to client side physics replication (until coming to rest or timeout period is hit)
UFUNCTION(BlueprintCallable, Category = "Networking") UFUNCTION(BlueprintCallable, Category = "Networking")
@ -148,32 +162,31 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
protected:
// Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip. // Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip.
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
bool bAllowIgnoringAttachOnOwner; bool bAllowIgnoringAttachOnOwner;
// Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled) public:
inline bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const
{
if ((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client)
return false;
if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive || void SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner);
VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) inline bool GetAllowIgnoringAttachOnOwner() { return bAllowIgnoringAttachOnOwner; };
{
return HasLocalNetOwner(); // Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled)
} /*inline*/ bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const;
else
return false;
}
// Fix bugs with replication and bReplicateMovement // Fix bugs with replication and bReplicateMovement
virtual void OnRep_AttachmentReplication() override; virtual void OnRep_AttachmentReplication() override;
@ -199,12 +212,22 @@ public:
// On Destroy clean up our objects // On Destroy clean up our objects
virtual void BeginDestroy() override; virtual void BeginDestroy() override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity
virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override;

View file

@ -35,6 +35,7 @@ public:
virtual void GetWeldedBodies(TArray<FBodyInstance*>& OutWeldedBodies, TArray<FName>& OutLabels, bool bIncludingAutoWeld) override; virtual void GetWeldedBodies(TArray<FBodyInstance*>& OutWeldedBodies, TArray<FName>& OutLabels, bool bIncludingAutoWeld) override;
virtual FBodyInstance* GetBodyInstance(FName BoneName = NAME_None, bool bGetWelded = true, int32 Index = INDEX_NONE) const override; virtual FBodyInstance* GetBodyInstance(FName BoneName = NAME_None, bool bGetWelded = true, int32 Index = INDEX_NONE) const override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -43,6 +44,12 @@ public:
// where the object will never have a replicating script // where the object will never have a replicating script
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
@ -81,10 +88,15 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
@ -98,6 +110,7 @@ public:
// This one is for components to clean up // This one is for components to clean up
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
protected:
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
@ -110,6 +123,16 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
void SetReplicateMovement(bool bNewReplicateMovement);
inline bool GetReplicateMovement() { return bReplicateMovement; };
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity

View file

@ -31,6 +31,7 @@ public:
virtual void BeginPlay() override; virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override; virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -39,6 +40,13 @@ public:
// where the object will never have a replicating script // where the object will never have a replicating script
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
@ -77,9 +85,12 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
@ -94,6 +105,7 @@ public:
// This one is for components to clean up // This one is for components to clean up
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
protected:
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
@ -106,6 +118,16 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
void SetReplicateMovement(bool bNewReplicateMovement);
inline bool GetReplicateMovement() { return bReplicateMovement; };
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity

View file

@ -60,6 +60,8 @@ public:
virtual void GatherCurrentMovement() override; virtual void GatherCurrentMovement() override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -69,6 +71,14 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& ObjList) override; virtual void GetSubobjectsWithStableNamesForNetworking(TArray<UObject*>& ObjList) override;
@ -101,9 +111,15 @@ public:
// Client Auth Throwing Data and functions // Client Auth Throwing Data and functions
// ------------------------------------------------ // ------------------------------------------------
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
FVRClientAuthReplicationData ClientAuthReplicationData; FVRClientAuthReplicationData ClientAuthReplicationData;
public:
// If changing this in c++ it is using a getter to make sure it is dirtied
FVRClientAuthReplicationData& GetClientAuthReplicationData(FVRClientAuthReplicationData& ClientAuthData);
// Add this to client side physics replication (until coming to rest or timeout period is hit) // Add this to client side physics replication (until coming to rest or timeout period is hit)
UFUNCTION(BlueprintCallable, Category = "Networking") UFUNCTION(BlueprintCallable, Category = "Networking")
bool AddToClientReplicationBucket(); bool AddToClientReplicationBucket();
@ -147,32 +163,29 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
protected:
// Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip. // Skips the attachment replication if we are locally owned and our grip settings say that we are a client authed grip.
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
bool bAllowIgnoringAttachOnOwner; bool bAllowIgnoringAttachOnOwner;
// Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled) public:
inline bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const void SetAllowIgnoringAttachOnOwner(bool bNewAllowIgnoringAttachOnOwner);
{ inline bool GetAllowIgnoringAttachOnOwner() { return bAllowIgnoringAttachOnOwner; };
if((bConsiderHeld && !VRGripInterfaceSettings.bWasHeld) || GetNetMode() < ENetMode::NM_Client)
return false;
if (VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive || // Should we skip attachment replication (vr settings say we are a client auth grip and our owner is locally controlled)
VRGripInterfaceSettings.MovementReplicationType == EGripMovementReplicationSettings::ClientSide_Authoritive_NoRep) /*inline*/ bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld = true) const;
{
return HasLocalNetOwner();
}
else
return false;
}
// Fix bugs with replication and bReplicateMovement // Fix bugs with replication and bReplicateMovement
virtual void OnRep_AttachmentReplication() override; virtual void OnRep_AttachmentReplication() override;
@ -198,12 +211,22 @@ public:
// On Destroy clean up our objects // On Destroy clean up our objects
virtual void BeginDestroy() override; virtual void BeginDestroy() override;
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity
virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override;

View file

@ -35,6 +35,8 @@ public:
// Gameplay tag interface // Gameplay tag interface
// ------------------------------------------------ // ------------------------------------------------
protected:
/** Overridden to return requirements tags */ /** Overridden to return requirements tags */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts; TArray<TObjectPtr<UVRGripScriptBase>> GripLogicScripts;
@ -45,6 +47,13 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bReplicateGripScripts; bool bReplicateGripScripts;
public:
void SetReplicateGripScripts(bool NewReplicateGripScripts);
inline bool GetReplicateGripScripts() { return bReplicateGripScripts; };
// Get the grip script array, will automatically dirty it if they are replicated as it is assumed if you are directly accessing it you are altering it
TArray<TObjectPtr<UVRGripScriptBase>>& GetGripLogicScripts();
bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override; bool ReplicateSubobjects(UActorChannel* Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override;
// Sets the Deny Gripping variable on the FBPInterfaceSettings struct // Sets the Deny Gripping variable on the FBPInterfaceSettings struct
@ -76,10 +85,15 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
public:
FGameplayTagContainer& GetGameplayTags();
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
@ -93,6 +107,7 @@ public:
// This one is for components to clean up // This one is for components to clean up
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override; virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
protected:
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bRepGripSettingsAndGameplayTags; bool bRepGripSettingsAndGameplayTags;
@ -106,6 +121,16 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
FBPInterfaceProperties VRGripInterfaceSettings; FBPInterfaceProperties VRGripInterfaceSettings;
public:
void SetRepGripSettingsAndGameplayTags(bool bNewRepGripSettingsAndGameplayTags);
inline bool GetRepGripSettingsAndGameplayTags() { return bRepGripSettingsAndGameplayTags; };
// Get VRGripInterfaceSettings, set MarkDirty if you intend to (or may) modify the values inside of it
FBPInterfaceProperties& GetVRGripInterfaceSettings(bool bMarkDirty);
void SetReplicateMovement(bool bNewReplicateMovement);
inline bool GetReplicateMovement() { return bReplicateMovement; };
// Set up as deny instead of allow so that default allows for gripping // Set up as deny instead of allow so that default allows for gripping
// The GripInitiator is not guaranteed to be valid, check it for validity // The GripInitiator is not guaranteed to be valid, check it for validity
virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override; virtual bool DenyGripping_Implementation(UGripMotionControllerComponent * GripInitiator = nullptr) override;

View file

@ -7,7 +7,9 @@
#include "GameplayTagAssetInterface.h" #include "GameplayTagAssetInterface.h"
#include "Components/SceneComponent.h" #include "Components/SceneComponent.h"
#include "Animation/AnimInstance.h" #include "Animation/AnimInstance.h"
#include "Animation/BoneReference.h"
#include "Misc/Guid.h" #include "Misc/Guid.h"
#include "HandSocketComponent.generated.h" #include "HandSocketComponent.generated.h"
class USkeletalMeshComponent; class USkeletalMeshComponent;
@ -409,6 +411,8 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
@ -423,6 +427,14 @@ public:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
FGameplayTagContainer& GetGameplayTags();
void SetRepGameplayTags(bool NewRepGameplayTags);
inline bool GetRepGameplayTags() { return bRepGameplayTags; };
void SetReplicateMovement(bool NewReplicateMovement);
inline bool GetReplicateMovement() { return bReplicateMovement; };
/** mesh component to indicate hand placement */ /** mesh component to indicate hand placement */
#if WITH_EDITORONLY_DATA #if WITH_EDITORONLY_DATA
@ -468,10 +480,5 @@ public:
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, transient, Category = "Socket Data") UPROPERTY(VisibleAnywhere, BlueprintReadOnly, transient, Category = "Socket Data")
TObjectPtr<UHandSocketComponent> OwningSocket; TObjectPtr<UHandSocketComponent> OwningSocket;
virtual void NativeInitializeAnimation() override virtual void NativeInitializeAnimation() override;
{
Super::NativeInitializeAnimation();
OwningSocket = Cast<UHandSocketComponent>(GetOwningComponent()->GetAttachParent());
}
}; };

View file

@ -111,6 +111,7 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent")
bool bIsEnabled; bool bIsEnabled;
protected:
// Current state of the button, writable to set initial value // Current state of the button, writable to set initial value
UPROPERTY(EditAnywhere,BlueprintReadWrite, Replicated, Category = "VRButtonComponent") UPROPERTY(EditAnywhere,BlueprintReadWrite, Replicated, Category = "VRButtonComponent")
bool bButtonState; bool bButtonState;
@ -118,6 +119,11 @@ public:
// Who is allowed to change the button state // Who is allowed to change the button state
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "VRButtonComponent|Replication") UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "VRButtonComponent|Replication")
EVRStateChangeAuthorityType StateChangeAuthorityType; EVRStateChangeAuthorityType StateChangeAuthorityType;
public:
bool GetButtonState() { return bButtonState; }
void SetButtonState(bool bNewButtonState);
EVRStateChangeAuthorityType GetStateChangeAuthorityType() { return StateChangeAuthorityType; }
void SetStateChangeAuthorityType(EVRStateChangeAuthorityType NewStateChangeAuthorityType);
// Speed that the button de-presses when no longer interacted with // Speed that the button de-presses when no longer interacted with
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRButtonComponent")
@ -155,18 +161,26 @@ public:
virtual FVector GetTargetRelativeLocation(); virtual FVector GetTargetRelativeLocation();
protected:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
// Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading.
virtual void OnRegister() override; virtual void OnRegister() override;
protected:
// Now replicating this so that it works correctly over the network // Now replicating this so that it works correctly over the network
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRButtonComponent") UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRButtonComponent")
FTransform_NetQuantize InitialRelativeTransform; FTransform_NetQuantize InitialRelativeTransform;
public:
// Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation
FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; }
UFUNCTION() UFUNCTION()
virtual void OnRep_InitialRelativeTransform() virtual void OnRep_InitialRelativeTransform()

View file

@ -120,9 +120,13 @@ public:
// Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading.
virtual void OnRegister() override; virtual void OnRegister() override;
protected:
// Now replicating this so that it works correctly over the network // Now replicating this so that it works correctly over the network
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRDialComponent") UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRDialComponent")
FTransform_NetQuantize InitialRelativeTransform; FTransform_NetQuantize InitialRelativeTransform;
public:
// Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation
FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; }
UFUNCTION() UFUNCTION()
virtual void OnRep_InitialRelativeTransform() virtual void OnRep_InitialRelativeTransform()
@ -161,15 +165,12 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGameplayTags; bool bRepGameplayTags;
@ -177,7 +178,14 @@ public:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
FGameplayTagContainer& GetGameplayTags();
bool GetRepGameplayTags() { return bRepGameplayTags; }
void SetRepGameplayTags(bool bNewRepGameplayTags);
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
virtual void BeginPlay() override; virtual void BeginPlay() override;

View file

@ -193,9 +193,13 @@ public:
// Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading.
virtual void OnRegister() override; virtual void OnRegister() override;
protected:
// Now replicating this so that it works correctly over the network // Now replicating this so that it works correctly over the network
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRLeverComponent") UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRLeverComponent")
FTransform_NetQuantize InitialRelativeTransform; FTransform_NetQuantize InitialRelativeTransform;
public:
// Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation
FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; }
UFUNCTION() UFUNCTION()
virtual void OnRep_InitialRelativeTransform() virtual void OnRep_InitialRelativeTransform()
@ -234,15 +238,12 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGameplayTags; bool bRepGameplayTags;
@ -250,7 +251,14 @@ public:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
FGameplayTagContainer& GetGameplayTags();
bool GetRepGameplayTags() { return bRepGameplayTags; }
void SetRepGameplayTags(bool bNewRepGameplayTags);
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
virtual void BeginPlay() override; virtual void BeginPlay() override;

View file

@ -94,15 +94,12 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGameplayTags; bool bRepGameplayTags;
@ -110,7 +107,14 @@ public:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
FGameplayTagContainer& GetGameplayTags();
bool GetRepGameplayTags() { return bRepGameplayTags; }
void SetRepGameplayTags(bool bNewRepGameplayTags);
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
virtual void BeginPlay() override; virtual void BeginPlay() override;
@ -146,11 +150,7 @@ public:
// Should be called after the Mount is moved post begin play // Should be called after the Mount is moved post begin play
UFUNCTION(BlueprintCallable, Category = "VRMountComponent") UFUNCTION(BlueprintCallable, Category = "VRMountComponent")
void ResetInitialMountLocation() void ResetInitialMountLocation();
{
// Get our initial relative transform to our parent (or not if un-parented).
InitialRelativeTransform = this->GetRelativeTransform();
}
virtual void OnUnregister() override;; virtual void OnUnregister() override;;

View file

@ -147,9 +147,13 @@ public:
UFUNCTION(BlueprintCallable, Category = "GripSettings") UFUNCTION(BlueprintCallable, Category = "GripSettings")
void SetGripPriority(int NewGripPriority); void SetGripPriority(int NewGripPriority);
protected:
// Set this to assign a spline component to the slider // Set this to assign a spline component to the slider
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated/*Using = OnRep_SplineComponentToFollow*/, Category = "VRSliderComponent") UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Replicated/*Using = OnRep_SplineComponentToFollow*/, Category = "VRSliderComponent")
TObjectPtr<USplineComponent> SplineComponentToFollow; TObjectPtr<USplineComponent> SplineComponentToFollow;
public:
// Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation
TObjectPtr<USplineComponent> GetSplineComponentToFollow() { return SplineComponentToFollow; }
/*UFUNCTION() /*UFUNCTION()
virtual void OnRep_SplineComponentToFollow() virtual void OnRep_SplineComponentToFollow()
@ -198,9 +202,13 @@ public:
// Resetting the initial transform here so that it comes in prior to BeginPlay and save loading. // Resetting the initial transform here so that it comes in prior to BeginPlay and save loading.
virtual void OnRegister() override; virtual void OnRegister() override;
protected:
// Now replicating this so that it works correctly over the network // Now replicating this so that it works correctly over the network
UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRSliderComponent") UPROPERTY(BlueprintReadOnly, ReplicatedUsing = OnRep_InitialRelativeTransform, Category = "VRSliderComponent")
FTransform_NetQuantize InitialRelativeTransform; FTransform_NetQuantize InitialRelativeTransform;
public:
// Gets the initial relative transform, if you want to set it you should be using ResetInitialButtonLocation
FTransform GetInitialRelativeTransform() { return InitialRelativeTransform; }
UFUNCTION() UFUNCTION()
virtual void OnRep_InitialRelativeTransform() virtual void OnRep_InitialRelativeTransform()
@ -261,15 +269,13 @@ public:
TagContainer = GameplayTags; TagContainer = GameplayTags;
} }
protected:
/** Tags that are set on this object */ /** Tags that are set on this object */
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
FGameplayTagContainer GameplayTags; FGameplayTagContainer GameplayTags;
// End Gameplay Tag Interface // End Gameplay Tag Interface
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
// Requires bReplicates to be true for the component // Requires bReplicates to be true for the component
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
bool bRepGameplayTags; bool bRepGameplayTags;
@ -277,7 +283,14 @@ public:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface|Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
FGameplayTagContainer& GetGameplayTags();
bool GetRepGameplayTags() { return bRepGameplayTags; }
void SetRepGameplayTags(bool bNewRepGameplayTags);
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
virtual void BeginPlay() override; virtual void BeginPlay() override;

View file

@ -216,15 +216,7 @@ public:
Super::Initialize(Collection); Super::Initialize(Collection);
} }
virtual void Deinitialize() override virtual void Deinitialize() override;
{
Super::Deinitialize();
if (UpdateHandle.IsValid())
{
GetWorld()->GetTimerManager().ClearTimer(UpdateHandle);
}
}
UPROPERTY() UPROPERTY()
TMap<FCollisionPrimPair, FCollisionIgnorePairArray> CollisionTrackedPairs; TMap<FCollisionPrimPair, FCollisionIgnorePairArray> CollisionTrackedPairs;

View file

@ -20,8 +20,12 @@ class VREXPANSIONPLUGIN_API UNoRepSphereComponent : public USphereComponent
public: public:
UNoRepSphereComponent(const FObjectInitializer& ObjectInitializer); UNoRepSphereComponent(const FObjectInitializer& ObjectInitializer);
protected:
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker) override;
}; };
@ -63,11 +67,14 @@ class VREXPANSIONPLUGIN_API UInversePhysicsSkeletalMeshComponent : public USkele
public: public:
UInversePhysicsSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer); UInversePhysicsSkeletalMeshComponent(const FObjectInitializer& ObjectInitializer);
public: protected:
// Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components // Overrides the default of : true and allows for controlling it like in an actor, should be default of off normally with grippable components
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication")
bool bReplicateMovement; bool bReplicateMovement;
public:
bool GetReplicateMovement() { return bReplicateMovement; }
void SetReplicateMovement(bool bNewReplicateMovement);
// This is all overrides to fix the skeletal mesh inverse simulation bug // This is all overrides to fix the skeletal mesh inverse simulation bug
// WILL BE REMOVED LATER when the engine is fixed // WILL BE REMOVED LATER when the engine is fixed

View file

@ -377,6 +377,8 @@ protected:
void RemoveAllQueriesByListener(const FPerceptionListener& Listener, const TFunction<void(const FAISightQueryVR&)>& OnRemoveFunc = nullptr); void RemoveAllQueriesByListener(const FPerceptionListener& Listener, const TFunction<void(const FAISightQueryVR&)>& OnRemoveFunc = nullptr);
void RemoveAllQueriesToTarget(const FAISightTargetVR::FTargetId& TargetId, const TFunction<void(const FAISightQueryVR&)>& OnRemoveFunc = nullptr); void RemoveAllQueriesToTarget(const FAISightTargetVR::FTargetId& TargetId, const TFunction<void(const FAISightQueryVR&)>& OnRemoveFunc = nullptr);
/** RemoveAllQueriesToTarget version that need to already have a write access on QueriesListAccessDetector*/
void RemoveAllQueriesToTarget_Internal(const FAISightTargetVR::FTargetId& TargetId, const TFunction<void(const FAISightQueryVR&)>& OnRemoveFunc = nullptr);
/** returns information whether new LoS queries have been added */ /** returns information whether new LoS queries have been added */
bool RegisterTarget(AActor& TargetActor, const TFunction<void(FAISightQueryVR&)>& OnAddedFunc = nullptr); bool RegisterTarget(AActor& TargetActor, const TFunction<void(FAISightQueryVR&)>& OnAddedFunc = nullptr);

View file

@ -5,8 +5,8 @@
//#include "UObject/ObjectMacros.h" //#include "UObject/ObjectMacros.h"
#include "Components/ActorComponent.h" #include "Components/ActorComponent.h"
#include "EngineDefines.h" #include "EngineDefines.h"
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
#include "Chaos/DebugDrawQueue.h" //#include "Chaos/DebugDrawQueue.h"
#endif #endif
#include "VREPhysicalAnimationComponent.generated.h" #include "VREPhysicalAnimationComponent.generated.h"
@ -89,11 +89,11 @@ public:
/** If true then we will debug draw the mesh collision post shape alterations */ /** If true then we will debug draw the mesh collision post shape alterations */
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WeldedBoneDriver) //UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = WeldedBoneDriver)
bool bDebugDrawCollision = false; //bool bDebugDrawCollision = false;
#if ENABLE_DRAW_DEBUG #if UE_ENABLE_DEBUG_DRAWING
void DebugDrawMesh(const TArray<Chaos::FLatentDrawCommand>& DrawCommands); //void DebugDrawMesh(const TArray<Chaos::FLatentDrawCommand>& DrawCommands);
#endif #endif
FTransform GetWorldSpaceRefBoneTransform(FReferenceSkeleton& RefSkel, int32 BoneIndex, int32 ParentBoneIndex); FTransform GetWorldSpaceRefBoneTransform(FReferenceSkeleton& RefSkel, int32 BoneIndex, int32 ParentBoneIndex);

View file

@ -3,6 +3,7 @@
#pragma once #pragma once
#include "CoreMinimal.h" #include "CoreMinimal.h"
#include "Components/ActorComponent.h"
#include "Engine/Canvas.h" #include "Engine/Canvas.h"
#include "Engine/TextureRenderTarget2D.h" #include "Engine/TextureRenderTarget2D.h"
#include "Engine/Console.h" #include "Engine/Console.h"

View file

@ -1,5 +1,8 @@
#pragma once #pragma once
#include "TimerManager.h" #include "TimerManager.h"
#include "GameFramework/Actor.h"
#include "Components/ActorComponent.h"
#include "Containers/Queue.h"
#include "VRRenderTargetManager.generated.h" #include "VRRenderTargetManager.generated.h"
class UVRRenderTargetManager; class UVRRenderTargetManager;
@ -8,6 +11,8 @@ class UCanvas;
class UTexture2D; class UTexture2D;
class UMaterial; class UMaterial;
class APlayerController; class APlayerController;
class FRenderCommandFence;
enum EPixelFormat : uint8;
// #TODO: Dirty rects so don't have to send entire texture? // #TODO: Dirty rects so don't have to send entire texture?
@ -214,14 +219,7 @@ public:
UPROPERTY() UPROPERTY()
int32 MaxBytesPerSecondRate; int32 MaxBytesPerSecondRate;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
{
if(SendTimer_Handle.IsValid())
GetWorld()->GetTimerManager().ClearTimer(SendTimer_Handle);
Super::EndPlay(EndPlayReason);
}
UFUNCTION(Reliable, Server, WithValidation) UFUNCTION(Reliable, Server, WithValidation)
void SendLocalDrawOperations(const TArray<FRenderManagerOperation>& LocalRenderOperationStoreList); void SendLocalDrawOperations(const TArray<FRenderManagerOperation>& LocalRenderOperationStoreList);

View file

@ -0,0 +1,154 @@
// Fill out your copyright notice in the Description page of Project Settings.
#pragma once
#include "CoreMinimal.h"
#include "MoverComponent.h"
#include "MoverTypes.h"
#include "GameFramework/Pawn.h"
#include "LayeredMove.h"
#include "VRMoverComponent.generated.h"
class UCurveVector;
class UCurveFloat;
DECLARE_LOG_CATEGORY_EXTERN(LogVRMoverComponent, Log, All);
/** Linear Velocity: A method of inducing a straight-line velocity on an actor over time */
USTRUCT(BlueprintType)
struct VREXPANSIONPLUGIN_API FLayeredMove_VRMovement : public FLayeredMoveBase
{
GENERATED_USTRUCT_BODY()
FLayeredMove_VRMovement();
virtual ~FLayeredMove_VRMovement() {}
// Units per second, could be worldspace vs relative depending on Flags
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover)
FVector Velocity;
// Optional curve float for controlling the magnitude of the velocity applied to the actor over the duration of the move
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover)
TObjectPtr<UCurveFloat> MagnitudeOverTime;
// @see ELayeredMove_ConstantVelocitySettingsFlags
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = Mover)
uint8 SettingsFlags;
// Never finish this movement
virtual bool IsFinished(float CurrentSimTimeMs) const;
// Generate a movement
virtual bool GenerateMove(const FMoverTickStartData& StartState, const FMoverTimeStep& TimeStep, const UMoverComponent* MoverComp, UMoverBlackboard* SimBlackboard, FProposedMove& OutProposedMove) override;
virtual FLayeredMoveBase* Clone() const override;
virtual void NetSerialize(FArchive& Ar) override;
virtual UScriptStruct* GetScriptStruct() const override;
virtual FString ToSimpleString() const override;
virtual void AddReferencedObjects(class FReferenceCollector& Collector) override;
};
template<>
struct TStructOpsTypeTraits< FLayeredMove_VRMovement > : public TStructOpsTypeTraitsBase2< FLayeredMove_VRMovement >
{
enum
{
//WithNetSerializer = true,
WithCopy = true
};
};
// Data block containing basic sync state information
USTRUCT(BlueprintType)
struct VREXPANSIONPLUGIN_API FVRMoverHMDSyncState : public FMoverDataStructBase
{
GENERATED_USTRUCT_BODY()
public:
// Movement intent direction relative to MovementBase if set, world space otherwise. Magnitude of range (0-1)
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = Mover)
FVector MoveDirectionIntent;
public:
FVRMoverHMDSyncState()
{
// In constructor list when the actual var is made
MoveDirectionIntent = FVector::ZeroVector;
}
virtual ~FVRMoverHMDSyncState() {}
// @return newly allocated copy of this FMoverDefaultSyncState. Must be overridden by child classes
virtual FMoverDataStructBase* Clone() const override;
virtual bool NetSerialize(FArchive& Ar, UPackageMap* Map, bool& bOutSuccess) override;
virtual UScriptStruct* GetScriptStruct() const override { return StaticStruct(); }
// Need implemented (if needed)
virtual bool ShouldReconcile(const FMoverDataStructBase& AuthorityState) const override
{
return false;
}
// Needs implemented (should we even do this?)
virtual void Interpolate(const FMoverDataStructBase& From, const FMoverDataStructBase& To, float Pct) override
{
return;
}
};
template<>
struct TStructOpsTypeTraits< FVRMoverHMDSyncState > : public TStructOpsTypeTraitsBase2< FVRMoverHMDSyncState >
{
enum
{
WithNetSerializer = true,
WithCopy = true
};
};
UCLASS()
class VREXPANSIONPLUGIN_API AVRMoverBasePawn : public APawn, public IMoverInputProducerInterface
{
GENERATED_BODY()
public:
// Sets default values for this pawn's properties
AVRMoverBasePawn(const FObjectInitializer& ObjectInitializer);
/** Accessor for the actor's movement component */
UFUNCTION(BlueprintPure, Category = Mover)
UMoverComponent* GetMoverComponent() const { return CharacterMotionComponent; }
virtual void BeginPlay() override;
protected:
virtual UPrimitiveComponent* GetMovementBase() const override;
// Entry point for input production. Do not override. To extend in derived character types, override OnProduceInput for native types or implement "Produce Input" blueprint event
virtual void ProduceInput_Implementation(int32 SimTimeMs, FMoverInputCmdContext& InputCmdResult) override;
// Override this function in native class to author input for the next simulation frame. Consider also calling Super method.
virtual void OnProduceInput(float DeltaMs, FMoverInputCmdContext& InputCmdResult);
// Implement this event in Blueprints to author input for the next simulation frame. Consider also calling Parent event.
UFUNCTION(BlueprintImplementableEvent, DisplayName = "On Produce Input", meta = (ScriptName = "OnProduceInput"))
FMoverInputCmdContext OnProduceInputInBlueprint(float DeltaMs, FMoverInputCmdContext InputCmd);
protected:
UPROPERTY(Category = Movement, VisibleAnywhere, BlueprintReadOnly, meta = (AllowPrivateAccess = "true"))
TObjectPtr<UMoverComponent> CharacterMotionComponent;
uint8 bHasProduceInputinBpFunc : 1;
};

View file

@ -106,6 +106,11 @@ public:
UPROPERTY(EditDefaultsOnly, ReplicatedUsing = OnRep_ReplicatedCameraTransform, Category = "ReplicatedCamera|Networking") UPROPERTY(EditDefaultsOnly, ReplicatedUsing = OnRep_ReplicatedCameraTransform, Category = "ReplicatedCamera|Networking")
FBPVRComponentPosRep ReplicatedCameraTransform; FBPVRComponentPosRep ReplicatedCameraTransform;
// Returns the actual tracked transform of the HMD, as with RetainRoomscale = False we do not set the camera to it
// Can also just use the HMD function library but this is a fast way if you already have a camera reference
UFUNCTION(BlueprintPure, Category = "ReplicatedCamera|Tracking")
FTransform GetHMDTrackingTransform();
FVector LastUpdatesRelativePosition = FVector::ZeroVector; FVector LastUpdatesRelativePosition = FVector::ZeroVector;
FRotator LastUpdatesRelativeRotation = FRotator::ZeroRotator; FRotator LastUpdatesRelativeRotation = FRotator::ZeroRotator;
@ -115,9 +120,10 @@ public:
// Run the smoothing step // Run the smoothing step
void RunNetworkedSmoothing(float DeltaTime); void RunNetworkedSmoothing(float DeltaTime);
// Whether to smooth (lerp) between ticks for the replicated motion, DOES NOTHING if update rate is larger than FPS! // Whether to smooth (lerp) between ticks for the replicated motion, DOES NOTHING if update rate is larger than FPS!
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "ReplicatedCamera|Networking") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "ReplicatedCamera|Networking")
bool bSmoothReplicatedMotion; bool bSmoothReplicatedMotion = true;
// If true then we will use exponential smoothing with buffered correction // If true then we will use exponential smoothing with buffered correction
UPROPERTY(EditAnywhere, Category = "ReplicatedCamera|Networking|Smoothing", meta = (editcondition = "bSmoothReplicatedMotion")) UPROPERTY(EditAnywhere, Category = "ReplicatedCamera|Networking|Smoothing", meta = (editcondition = "bSmoothReplicatedMotion"))
@ -138,14 +144,19 @@ public:
UFUNCTION() UFUNCTION()
virtual void OnRep_ReplicatedCameraTransform(); virtual void OnRep_ReplicatedCameraTransform();
protected:
// Rate to update the position to the server, 100htz is default (same as replication rate, should also hit every tick). // Rate to update the position to the server, 100htz is default (same as replication rate, should also hit every tick).
// On dedicated servers the update rate should be at or lower than the server tick rate for smoothing to work // On dedicated servers the update rate should be at or lower than the server tick rate for smoothing to work
UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "ReplicatedCamera|Networking") UPROPERTY(EditAnywhere, BlueprintReadWrite, Replicated, Category = "ReplicatedCamera|Networking")
float NetUpdateRate; float NetUpdateRate;
public:
// Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case. // Used in Tick() to accumulate before sending updates, didn't want to use a timer in this case.
float NetUpdateCount; float NetUpdateCount;
float GetNetUpdateRate() { return NetUpdateRate; }
void SetNetUpdateRate(float NewNetUpdateRate);
// I'm sending it unreliable because it is being resent pretty often // I'm sending it unreliable because it is being resent pretty often
UFUNCTION(Unreliable, Server, WithValidation) UFUNCTION(Unreliable, Server, WithValidation)
void Server_SendCameraTransform(FBPVRComponentPosRep NewTransform); void Server_SendCameraTransform(FBPVRComponentPosRep NewTransform);
@ -155,14 +166,7 @@ public:
VRBaseCharTransformRPC_Pointer OverrideSendTransform; VRBaseCharTransformRPC_Pointer OverrideSendTransform;
// Need this as I can't think of another way for an actor component to make sure it isn't on the server // Need this as I can't think of another way for an actor component to make sure it isn't on the server
inline bool IsLocallyControlled() const bool IsLocallyControlled() const;
{
// I like epics new authority check more than my own
const AActor* MyOwner = GetOwner();
return MyOwner->HasLocalNetOwner();
//const APawn* MyPawn = Cast<APawn>(MyOwner);
//return MyPawn ? MyPawn->IsLocallyControlled() : false;// (MyOwner->Role == ENetRole::ROLE_Authority);
}
//bool IsServer(); //bool IsServer();
}; };

View file

@ -14,6 +14,7 @@
class UGripMotionControllerComponent; class UGripMotionControllerComponent;
class UVRGripScriptBase; class UVRGripScriptBase;
class UPrimitiveComponent;
// Custom movement modes for the characters // Custom movement modes for the characters
UENUM(BlueprintType) UENUM(BlueprintType)
@ -186,9 +187,9 @@ public:
if (!bFirstTime) if (!bFirstTime)
{ {
// This is unsafe in non float / float array data types, but I am not going to be using any like that // This is unsafe in non float / float array data types, but I am not going to be using any like that
for (int i = 0; i < sizeof(filterType)/sizeof(float); i++) for (int i = 0; i < sizeof(filterType) / sizeof(double); i++)
{ {
((float*)&Result)[i] = ((float*)&InAlpha)[i] * ((float*)&InValue)[i] + (1.0f - ((float*)&InAlpha)[i]) * ((float*)&Previous)[i]; ((double*)&Result)[i] = ((double*)&InAlpha)[i] * ((double*)&InValue)[i] + (1.0f - ((double*)&InAlpha)[i]) * ((double*)&Previous)[i];
} }
} }
@ -211,13 +212,13 @@ public:
//private: //private:
const filterType CalculateCutoff(const filterType& InValue, float& MinCutoff, float& CutoffSlope) const filterType CalculateCutoff(const filterType& InValue, double& MinCutoff, double& CutoffSlope)
{ {
filterType Result; filterType Result;
// This is unsafe in non float / float array data types, but I am not going to be using any like that // This is unsafe in non float / float array data types, but I am not going to be using any like that
for (int i = 0; i < sizeof(filterType)/sizeof(float); i++) for (int i = 0; i < sizeof(filterType) / sizeof(double); i++)
{ {
((float*)&Result)[i] = MinCutoff + CutoffSlope * FMath::Abs(((float*)&InValue)[i]); ((double*)&Result)[i] = MinCutoff + CutoffSlope * FMath::Abs(((double*)&InValue)[i]);
} }
return Result; return Result;
} }
@ -226,17 +227,17 @@ public:
{ {
filterType Result; filterType Result;
// This is unsafe in non float / float array data types, but I am not going to be using any like that // This is unsafe in non float / float array data types, but I am not going to be using any like that
for (int i = 0; i < sizeof(filterType)/sizeof(float); i++) for (int i = 0; i < sizeof(filterType) / sizeof(double); i++)
{ {
((float*)&Result)[i] = CalculateAlphaTau(((float*)&InCutoff)[i], InDeltaTime); ((double*)&Result)[i] = CalculateAlphaTau(((double*)&InCutoff)[i], InDeltaTime);
} }
return Result; return Result;
} }
inline const float CalculateAlphaTau(const float InCutoff, const double InDeltaTime) inline const double CalculateAlphaTau(const double InCutoff, const double InDeltaTime)
{ {
const float tau = 1.0 / (2.0f * PI * InCutoff); const double tau = 1.0 / (2.0 * PI * InCutoff);
return 1.0f / (1.0f + tau / InDeltaTime); return 1.0 / (1.0 + tau / InDeltaTime);
} }
}; };
@ -254,14 +255,14 @@ public:
/** Default constructor */ /** Default constructor */
FBPEuroLowPassFilter() : FBPEuroLowPassFilter() :
MinCutoff(0.9f), MinCutoff(0.9),
DeltaCutoff(1.0f), DeltaCutoff(1.0),
CutoffSlope(0.007f), CutoffSlope(0.007),
RawFilter(FVector::ZeroVector), RawFilter(FVector::ZeroVector),
DeltaFilter(FVector::ZeroVector) DeltaFilter(FVector::ZeroVector)
{} {}
FBPEuroLowPassFilter(const float InMinCutoff, const float InCutoffSlope, const float InDeltaCutoff) : FBPEuroLowPassFilter(const double InMinCutoff, const double InCutoffSlope, const double InDeltaCutoff) :
MinCutoff(InMinCutoff), MinCutoff(InMinCutoff),
DeltaCutoff(InDeltaCutoff), DeltaCutoff(InDeltaCutoff),
CutoffSlope(InCutoffSlope), CutoffSlope(InCutoffSlope),
@ -271,15 +272,15 @@ public:
// The smaller the value the less jitter and the more lag with micro movements // The smaller the value the less jitter and the more lag with micro movements
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float MinCutoff; double MinCutoff;
// If latency is too high with fast movements increase this value // If latency is too high with fast movements increase this value
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float DeltaCutoff; double DeltaCutoff;
// This is the magnitude of adjustment // This is the magnitude of adjustment
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float CutoffSlope; double CutoffSlope;
void ResetSmoothingFilter(); void ResetSmoothingFilter();
@ -308,14 +309,14 @@ public:
/** Default constructor */ /** Default constructor */
FBPEuroLowPassFilterQuat() : FBPEuroLowPassFilterQuat() :
MinCutoff(0.9f), MinCutoff(0.9),
DeltaCutoff(1.0f), DeltaCutoff(1.0),
CutoffSlope(0.007f), CutoffSlope(0.007),
RawFilter(FQuat::Identity), RawFilter(FQuat::Identity),
DeltaFilter(FQuat::Identity) DeltaFilter(FQuat::Identity)
{} {}
FBPEuroLowPassFilterQuat(const float InMinCutoff, const float InCutoffSlope, const float InDeltaCutoff) : FBPEuroLowPassFilterQuat(const double InMinCutoff, const double InCutoffSlope, const double InDeltaCutoff) :
MinCutoff(InMinCutoff), MinCutoff(InMinCutoff),
DeltaCutoff(InDeltaCutoff), DeltaCutoff(InDeltaCutoff),
CutoffSlope(InCutoffSlope), CutoffSlope(InCutoffSlope),
@ -325,15 +326,15 @@ public:
// The smaller the value the less jitter and the more lag with micro movements // The smaller the value the less jitter and the more lag with micro movements
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float MinCutoff; double MinCutoff;
// If latency is too high with fast movements increase this value // If latency is too high with fast movements increase this value
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float DeltaCutoff; double DeltaCutoff;
// This is the magnitude of adjustment // This is the magnitude of adjustment
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float CutoffSlope; double CutoffSlope;
void ResetSmoothingFilter(); void ResetSmoothingFilter();
@ -361,14 +362,14 @@ public:
/** Default constructor */ /** Default constructor */
FBPEuroLowPassFilterTrans() : FBPEuroLowPassFilterTrans() :
MinCutoff(0.1f), MinCutoff(0.1),
DeltaCutoff(10.0f), DeltaCutoff(10.0),
CutoffSlope(10.0f), CutoffSlope(10.0),
RawFilter(FTransform::Identity), RawFilter(FTransform::Identity),
DeltaFilter(FTransform::Identity) DeltaFilter(FTransform::Identity)
{} {}
FBPEuroLowPassFilterTrans(const float InMinCutoff, const float InCutoffSlope, const float InDeltaCutoff) : FBPEuroLowPassFilterTrans(const double InMinCutoff, const double InCutoffSlope, const double InDeltaCutoff) :
MinCutoff(InMinCutoff), MinCutoff(InMinCutoff),
DeltaCutoff(InDeltaCutoff), DeltaCutoff(InDeltaCutoff),
CutoffSlope(InCutoffSlope), CutoffSlope(InCutoffSlope),
@ -378,15 +379,15 @@ public:
// The smaller the value the less jitter and the more lag with micro movements // The smaller the value the less jitter and the more lag with micro movements
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float MinCutoff; double MinCutoff;
// If latency is too high with fast movements increase this value // If latency is too high with fast movements increase this value
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float DeltaCutoff; double DeltaCutoff;
// This is the magnitude of adjustment // This is the magnitude of adjustment
UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings") UPROPERTY(BlueprintReadWrite, EditAnywhere, Category = "FilterSettings")
float CutoffSlope; double CutoffSlope;
void ResetSmoothingFilter(); void ResetSmoothingFilter();
@ -1467,6 +1468,13 @@ public:
float LerpSpeed; float LerpSpeed;
FTransform OnGripTransform; FTransform OnGripTransform;
/////////////////////
// TMP: Velocity calculation addition for 5.4 #TODO: Remove this when the bug is fixed
FVector LinVel = FVector::ZeroVector;
FVector RotVel = FVector::ZeroVector;
FTransform LastVelWorldTrans; // Identity by default
///////////////////////
UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings") UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "Settings")
bool bIsLerping; bool bIsLerping;
@ -1550,15 +1558,9 @@ public:
} }
FORCEINLINE AActor * GetGrippedActor() const AActor* GetGrippedActor() const;
{
return Cast<AActor>(GrippedObject);
}
FORCEINLINE UPrimitiveComponent * GetGrippedComponent() const UPrimitiveComponent* GetGrippedComponent() const;
{
return Cast<UPrimitiveComponent>(GrippedObject);
}
//Check if a grip is the same as another, the only things I check for are the actor / component //Check if a grip is the same as another, the only things I check for are the actor / component
//This is here for the Find() function from TArray //This is here for the Find() function from TArray
@ -1580,13 +1582,7 @@ public:
return false; return false;
} }
FORCEINLINE bool operator==(const UPrimitiveComponent * Other) const bool operator==(const UPrimitiveComponent* Other) const;
{
if (Other && GrippedObject && GrippedObject == (const UObject*)Other)
return true;
return false;
}
FORCEINLINE bool operator==(const UObject * Other) const FORCEINLINE bool operator==(const UObject * Other) const
{ {
@ -1868,11 +1864,11 @@ public:
bEnableVelocityDrive = ConstraintDrive.bEnableVelocityDrive; bEnableVelocityDrive = ConstraintDrive.bEnableVelocityDrive;
} }
void FillTo(FConstraintDrive& ConstraintDrive) const void FillTo(FConstraintDrive& ConstraintDrive, float DampingScaler = 1.0f, float StiffnessScaler = 1.0f) const
{ {
ConstraintDrive.Damping = Damping; ConstraintDrive.Damping = Damping * DampingScaler;
ConstraintDrive.Stiffness = Stiffness; ConstraintDrive.Stiffness = Stiffness * StiffnessScaler;
ConstraintDrive.MaxForce = MaxForceCoefficient * Stiffness; ConstraintDrive.MaxForce = (float)FMath::Clamp<double>((double)ConstraintDrive.Stiffness * (double)MaxForceCoefficient, 0, (double)MAX_FLT);
ConstraintDrive.bEnablePositionDrive = bEnablePositionDrive; ConstraintDrive.bEnablePositionDrive = bEnablePositionDrive;
ConstraintDrive.bEnableVelocityDrive = bEnableVelocityDrive; ConstraintDrive.bEnableVelocityDrive = bEnableVelocityDrive;
} }
@ -1929,27 +1925,5 @@ public:
return true; return true;
} }
bool FillTo(FBPActorPhysicsHandleInformation* HandleInfo) const bool FillTo(FBPActorPhysicsHandleInformation* HandleInfo, bool bModifyWithScalers = true) const;
{
if (!HandleInfo)
return false;
XAxisSettings.FillTo(HandleInfo->LinConstraint.XDrive);
YAxisSettings.FillTo(HandleInfo->LinConstraint.YDrive);
ZAxisSettings.FillTo(HandleInfo->LinConstraint.ZDrive);
if ((SlerpSettings.bEnablePositionDrive || SlerpSettings.bEnableVelocityDrive))
{
HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::SLERP;
SlerpSettings.FillTo(HandleInfo->AngConstraint.SlerpDrive);
}
else
{
HandleInfo->AngConstraint.AngularDriveMode = EAngularDriveMode::TwistAndSwing;
TwistSettings.FillTo(HandleInfo->AngConstraint.TwistDrive);
SwingSettings.FillTo(HandleInfo->AngConstraint.SwingDrive);
}
return true;
}
}; };

View file

@ -13,6 +13,7 @@ class AVRPlayerController;
class UGripMotionControllerComponent; class UGripMotionControllerComponent;
class UParentRelativeAttachmentComponent; class UParentRelativeAttachmentComponent;
class AController; class AController;
class UNavigationQueryFilter;
DECLARE_LOG_CATEGORY_EXTERN(LogBaseVRCharacter, Log, All); DECLARE_LOG_CATEGORY_EXTERN(LogBaseVRCharacter, Log, All);
@ -280,7 +281,7 @@ public:
// If true then we will retain roomscale tracking in relative space of the character. // If true then we will retain roomscale tracking in relative space of the character.
// If false than the movement component will offset to the hmd tracking and the tracking will be nulled out // If false than the movement component will offset to the hmd tracking and the tracking will be nulled out
UPROPERTY(Category = VRBaseCharacter, EditAnywhere, BlueprintReadOnly) UPROPERTY(Category = VRBaseCharacter, EditAnywhere, BlueprintReadOnly)
bool bRetainRoomscale = true; bool bRetainRoomscale = false;
//virtual void CacheInitialMeshOffset(FVector MeshRelativeLocation, FRotator MeshRelativeRotation) override; //virtual void CacheInitialMeshOffset(FVector MeshRelativeLocation, FRotator MeshRelativeRotation) override;
virtual void PostInitializeComponents() override; virtual void PostInitializeComponents() override;
@ -330,9 +331,14 @@ public:
virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override; virtual void PreReplication(IRepChangedPropertyTracker & ChangedPropertyTracker) override;
protected:
// If true will replicate the capsule height on to clients, allows for dynamic capsule height changes in multiplayer // If true will replicate the capsule height on to clients, allows for dynamic capsule height changes in multiplayer
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRBaseCharacter") UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRBaseCharacter")
bool VRReplicateCapsuleHeight; bool VRReplicateCapsuleHeight;
public:
bool GetVRReplicateCapsuleHeight() { return VRReplicateCapsuleHeight; }
void SetVRReplicateCapsuleHeight(bool bNewVRReplicateCapsuleHeight);
// OnlyReplicated to simulated clients // OnlyReplicated to simulated clients
UPROPERTY(Replicated, ReplicatedUsing = OnRep_CapsuleHeight) UPROPERTY(Replicated, ReplicatedUsing = OnRep_CapsuleHeight)

View file

@ -25,6 +25,10 @@ public:
virtual FVector GetTargetHeightOffset() override; virtual FVector GetTargetHeightOffset() override;
virtual void OnStartCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust) override;
virtual void OnEndCrouch(float HalfHeightAdjust, float ScaledHalfHeightAdjust) override;
// Regenerates the base offsetcomponenttoworld that VR uses // Regenerates the base offsetcomponenttoworld that VR uses
virtual void RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw) override; virtual void RegenerateOffsetComponentToWorld(bool bUpdateBounds, bool bCalculatePureYaw) override;
virtual void SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps = true) override; virtual void SetCharacterSizeVR(float NewRadius, float NewHalfHeight, bool bUpdateOverlaps = true) override;

View file

@ -6,6 +6,7 @@
//#include "Engine/Engine.h" //#include "Engine/Engine.h"
#include "VRBPDatatypes.h" #include "VRBPDatatypes.h"
#include "Engine/DataAsset.h" #include "Engine/DataAsset.h"
#include "Components\SceneComponent.h"
//#include "Engine/EngineTypes.h" //#include "Engine/EngineTypes.h"
//#include "Engine/EngineBaseTypes.h" //#include "Engine/EngineBaseTypes.h"
@ -37,6 +38,15 @@ enum class EVRGestureMirrorMode : uint8
GES_MirrorBoth GES_MirrorBoth
}; };
UENUM(Blueprintable)
enum class EVRGestureFlattenAxis : uint8
{
GES_FlattenX,
GES_FlattenY,
GES_FlattenZ,
GES_DontFlatten
};
USTRUCT(BlueprintType, Category = "VRGestures") USTRUCT(BlueprintType, Category = "VRGestures")
struct VREXPANSIONPLUGIN_API FVRGestureSettings struct VREXPANSIONPLUGIN_API FVRGestureSettings
{ {
@ -94,7 +104,7 @@ public:
uint8 GestureType; uint8 GestureType;
// Samples in the recorded gesture // Samples in the recorded gesture
UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "VRGesture") UPROPERTY(BlueprintReadWrite, EditDefaultsOnly, Category = "VRGesture")
TArray<FVector> Samples; TArray<FVector> Samples;
UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "VRGesture") UPROPERTY(BlueprintReadWrite, VisibleAnywhere, Category = "VRGesture")
@ -279,11 +289,11 @@ public:
// Number of samples to keep in memory during detection // Number of samples to keep in memory during detection
int RecordingBufferSize; int RecordingBufferSize;
float RecordingClampingTolerance; float RecordingClampingTolerance = 0.0f;
bool bRecordingFlattenGesture; EVRGestureFlattenAxis RecordingFlattenAxis = EVRGestureFlattenAxis::GES_DontFlatten;
bool bDrawRecordingGesture; bool bDrawRecordingGesture = false;
bool bDrawRecordingGestureAsSpline; bool bDrawRecordingGestureAsSpline = false;
bool bGestureChanged; bool bGestureChanged = false;
// Handle to our update timer // Handle to our update timer
FTimerHandle TickGestureTimer_Handle; FTimerHandle TickGestureTimer_Handle;
@ -309,7 +319,7 @@ public:
return FVector::DistSquared(Seq1, Seq2); return FVector::DistSquared(Seq1, Seq2);
} }
void BeginDestroy() override; virtual void BeginDestroy() override;
// Recalculates a gestures size and re-scales it to the given database // Recalculates a gestures size and re-scales it to the given database
UFUNCTION(BlueprintCallable, Category = "VRGestures") UFUNCTION(BlueprintCallable, Category = "VRGestures")
@ -335,7 +345,7 @@ public:
* ClampingTolerance: If larger than 0.0, we will clamp points to a grid of this size * ClampingTolerance: If larger than 0.0, we will clamp points to a grid of this size
*/ */
UFUNCTION(BlueprintCallable, Category = "VRGestures") UFUNCTION(BlueprintCallable, Category = "VRGestures")
void BeginRecording(bool bRunDetection, bool bFlattenGesture = true, bool bDrawGesture = true, bool bDrawAsSpline = false, int SamplingHTZ = 30, int SampleBufferSize = 60, float ClampingTolerance = 0.01f); void BeginRecording(bool bRunDetection, EVRGestureFlattenAxis FlattenAxis = EVRGestureFlattenAxis::GES_FlattenX, bool bDrawGesture = true, bool bDrawAsSpline = false, int SamplingHTZ = 30, int SampleBufferSize = 60, float ClampingTolerance = 0.01f);
// Ends recording and returns the recorded gesture // Ends recording and returns the recorded gesture
UFUNCTION(BlueprintCallable, Category = "VRGestures") UFUNCTION(BlueprintCallable, Category = "VRGestures")

View file

@ -230,6 +230,9 @@ public:
return bInsideVolume; return bInsideVolume;
} }
// Expose this
inline float GetLineThickness() const {return LineThickness;}
public: public:
// Begin UObject interface // Begin UObject interface
#if WITH_EDITOR #if WITH_EDITOR

View file

@ -117,6 +117,7 @@ public:
TObjectPtr<UStereoLayerShape> Shape; TObjectPtr<UStereoLayerShape> Shape;
void BeginDestroy() override; void BeginDestroy() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
void OnUnregister() override; void OnUnregister() override;
virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override; virtual void TickComponent(float DeltaTime, enum ELevelTick TickType, FActorComponentTickFunction *ThisTickFunction) override;
virtual void DrawWidgetToRenderTarget(float DeltaTime) override; virtual void DrawWidgetToRenderTarget(float DeltaTime) override;
@ -176,6 +177,10 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer") UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "StereoLayer")
uint32 bQuadPreserveTextureRatio : 1; uint32 bQuadPreserveTextureRatio : 1;
/** Additional flags not included in IStereoLayers::ELayerFlags */
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "StereoLayer", Meta = (GetOptions = "EditorFlagCollector.GetFlagNames"))
TArray<FName> AdditionalFlags;
protected: protected:
/** Texture displayed on the stereo layer (is stereocopic textures are supported on the platfrom and more than one texture is provided, this will be the right eye) **/ /** Texture displayed on the stereo layer (is stereocopic textures are supported on the platfrom and more than one texture is provided, this will be the right eye) **/
//UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "StereoLayer") //UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "StereoLayer")
@ -220,6 +225,9 @@ public:
UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer") UPROPERTY(EditAnywhere, BlueprintReadOnly, export, Category = "StereoLayer")
int32 Priority; int32 Priority;
/** IStereoLayer id, 0 is unassigned **/
uint32 LayerId;
bool bShouldCreateProxy; bool bShouldCreateProxy;
private: private:
@ -230,9 +238,6 @@ private:
/** Texture needs to be marked for update **/ /** Texture needs to be marked for update **/
bool bTextureNeedsUpdate; bool bTextureNeedsUpdate;
/** IStereoLayer id, 0 is unassigned **/
uint32 LayerId;
/** Last transform is cached to determine if the new frames transform has changed **/ /** Last transform is cached to determine if the new frames transform has changed **/
FTransform LastTransform; FTransform LastTransform;

View file

@ -59,23 +59,15 @@ public class VRExpansionPlugin : ModuleRules
"NetCore", "NetCore",
"CoreUObject", "CoreUObject",
"Engine", "Engine",
// "InputCore",
"PhysicsCore", "PhysicsCore",
//"FLEX", remove comment if building in the NVIDIA flex branch - NOTE when put in place FLEX only listed win32 and win64 at compatible platforms
"HeadMountedDisplay", "HeadMountedDisplay",
// "RHI",
//"RenderCore",
//"ShaderCore",
//"NetworkReplayStreaming",
//"AIModule",
"UMG", "UMG",
"NavigationSystem", "NavigationSystem",
"AIModule", "AIModule",
"AnimGraphRuntime", "AnimGraphRuntime",
"XRBase", "XRBase",
"GameplayTags" "GameplayTags",
//"Renderer", "Mover"
//"UtilityShaders"
}); });
//if(Target.bUseChaos) //if(Target.bUseChaos)
@ -114,20 +106,6 @@ public class VRExpansionPlugin : ModuleRules
} }
); );
// Don't load APEX on incompatible platforms
/* if (
Target.Platform != UnrealTargetPlatform.IOS &&
Target.Platform != UnrealTargetPlatform.TVOS &&
Target.Platform != UnrealTargetPlatform.Android &&
Target.Platform != UnrealTargetPlatform.HTML5)
{
PublicDependencyModuleNames.AddRange(
new string[]
{
"APEX"
});
}*/
// Allow gameplay debugger on editor builds // Allow gameplay debugger on editor builds
if (Target.bBuildDeveloperTools || (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Configuration != UnrealTargetConfiguration.Test)) if (Target.bBuildDeveloperTools || (Target.Configuration != UnrealTargetConfiguration.Shipping && Target.Configuration != UnrealTargetConfiguration.Test))
{ {

View file

@ -1,7 +1,7 @@
{ {
"FileVersion": 3, "FileVersion": 3,
"Version": 5.3, "Version": 5.4,
"VersionName": "5.3", "VersionName": "5.4",
"FriendlyName": "VRExpansionPlugin", "FriendlyName": "VRExpansionPlugin",
"Description": "Adds several new VR features & components to UE4", "Description": "Adds several new VR features & components to UE4",
"Category": "VRExpansion", "Category": "VRExpansion",
@ -41,6 +41,10 @@
{ {
"Name": "XRBase", "Name": "XRBase",
"Enabled": true "Enabled": true
},
{
"Name": "Mover",
"Enabled": true
} }
] ]
} }