A Demo Project for the UnrealEngineSDK
Loading...
Searching...
No Matches
GrippableSkeletalMeshActor.cpp
Go to the documentation of this file.
1// Copyright 1998-2016 Epic Games, Inc. All Rights Reserved.
2
4#include "TimerManager.h"
5#include "Net/UnrealNetwork.h"
6#include "PhysicsReplication.h"
7#if WITH_PUSH_MODEL
8#include "Net/Core/PushModel/PushModel.h"
9#endif
10
12 : Super(ObjectInitializer)
13{
14 bReplicateMovement = true;
15}
16
17void UOptionalRepSkeletalMeshComponent::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
18{
19 Super::PreReplication(ChangedPropertyTracker);
20
21 // Don't replicate if set to not do it
22 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(USceneComponent, RelativeLocation, bReplicateMovement);
23 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(USceneComponent, RelativeRotation, bReplicateMovement);
24 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(USceneComponent, RelativeScale3D, bReplicateMovement);
25}
26
27void UOptionalRepSkeletalMeshComponent::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const
28{
29 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
30
32}
33
34//=============================================================================
35AGrippableSkeletalMeshActor::AGrippableSkeletalMeshActor(const FObjectInitializer& ObjectInitializer)
36 : Super(ObjectInitializer.SetDefaultSubobjectClass<UOptionalRepSkeletalMeshComponent>(TEXT("SkeletalMeshComponent0")))
37{
51
53
54 // Default replication on for multiplayer
55 //this->bNetLoadOnClient = false;
56 SetReplicatingMovement(true);
57 bReplicates = true;
58
62
63 // Setting a minimum of every 3rd frame (VR 90fps) for replication consideration
64 // Otherwise we will get some massive slow downs if the replication is allowed to hit the 2 per second minimum default
65 MinNetUpdateFrequency = 30.0f;
66}
67
68void AGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty >& OutLifetimeProps) const
69{
70 Super::GetLifetimeReplicatedProps(OutLifetimeProps);
71
72 DOREPLIFETIME_CONDITION(AGrippableSkeletalMeshActor, GripLogicScripts, COND_Custom);
77 DOREPLIFETIME_CONDITION(AGrippableSkeletalMeshActor, VRGripInterfaceSettings, COND_Custom);
78 DOREPLIFETIME_CONDITION(AGrippableSkeletalMeshActor, GameplayTags, COND_Custom);
79
80 DISABLE_REPLICATED_PRIVATE_PROPERTY(AActor, AttachmentReplication);
81
82 FDoRepLifetimeParams AttachmentReplicationParams{ COND_Custom, REPNOTIFY_Always, /*bIsPushBased=*/true };
83 DOREPLIFETIME_WITH_PARAMS_FAST(AGrippableSkeletalMeshActor, AttachmentWeldReplication, AttachmentReplicationParams);
84}
85
86void AGrippableSkeletalMeshActor::PreReplication(IRepChangedPropertyTracker& ChangedPropertyTracker)
87{
88 // Don't replicate if set to not do it
92
93 //Super::PreReplication(ChangedPropertyTracker);
94
95#if WITH_PUSH_MODEL
96 const AActor* const OldAttachParent = AttachmentWeldReplication.AttachParent;
97 const UActorComponent* const OldAttachComponent = AttachmentWeldReplication.AttachComponent;
98#endif
99
100 // Attachment replication gets filled in by GatherCurrentMovement(), but in the case of a detached root we need to trigger remote detachment.
101 AttachmentWeldReplication.AttachParent = nullptr;
102 AttachmentWeldReplication.AttachComponent = nullptr;
103
105
106 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(AActor, ReplicatedMovement, IsReplicatingMovement());
107
108 // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it.
109 DOREPLIFETIME_ACTIVE_OVERRIDE(AGrippableSkeletalMeshActor, AttachmentWeldReplication, RootComponent && !RootComponent->GetIsReplicated());
110
111 // Don't need to replicate AttachmentReplication if the root component replicates, because it already handles it.
112 DOREPLIFETIME_ACTIVE_OVERRIDE_PRIVATE_PROPERTY(AActor, AttachmentReplication, RootComponent && !RootComponent->GetIsReplicated());
113
114
115#if WITH_PUSH_MODEL
116 if (UNLIKELY(OldAttachParent != AttachmentWeldReplication.AttachParent || OldAttachComponent != AttachmentWeldReplication.AttachComponent))
117 {
118 //MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, AttachmentWeldReplication, this);
119 }
120#endif
121
122 UBlueprintGeneratedClass* BPClass = Cast<UBlueprintGeneratedClass>(GetClass());
123 if (BPClass != nullptr)
124 {
125 BPClass->InstancePreReplication(this, ChangedPropertyTracker);
126 }
127}
128
130{
131 if (IsReplicatingMovement() || (RootComponent && RootComponent->GetAttachParent()))
132 {
133 bool bWasAttachmentModified = false;
134 bool bWasRepMovementModified = false;
135
136 AActor* OldAttachParent = AttachmentWeldReplication.AttachParent;
137 USceneComponent* OldAttachComponent = AttachmentWeldReplication.AttachComponent;
138
139 AttachmentWeldReplication.AttachParent = nullptr;
140 AttachmentWeldReplication.AttachComponent = nullptr;
141
142 FRepMovement& RepMovement = GetReplicatedMovement_Mutable();
143
144 UPrimitiveComponent* RootPrimComp = Cast<UPrimitiveComponent>(GetRootComponent());
145 if (RootPrimComp && RootPrimComp->IsSimulatingPhysics())
146 {
147 FRigidBodyState RBState;
148 RootPrimComp->GetRigidBodyState(RBState);
149
150 RepMovement.FillFrom(RBState, this);
151 // Don't replicate movement if we're welded to another parent actor.
152 // Their replication will affect our position indirectly since we are attached.
153 RepMovement.bRepPhysics = !RootPrimComp->IsWelded();
154
155 if (!RepMovement.bRepPhysics)
156 {
157 if (RootComponent->GetAttachParent() != nullptr)
158 {
159 // Networking for attachments assumes the RootComponent of the AttachParent actor.
160 // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result.
161 AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor();
162 if (AttachmentWeldReplication.AttachParent != nullptr)
163 {
164 AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation();
165 AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation();
166 AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D();
167 AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent();
168 AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName();
169 AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false;
170
171 // Technically, the values might have stayed the same, but we'll just assume they've changed.
172 bWasAttachmentModified = true;
173 }
174 }
175 }
176
177 // Technically, the values might have stayed the same, but we'll just assume they've changed.
178 bWasRepMovementModified = true;
179 }
180 else if (RootComponent != nullptr)
181 {
182 // If we are attached, don't replicate absolute position, use AttachmentReplication instead.
183 if (RootComponent->GetAttachParent() != nullptr)
184 {
185 // Networking for attachments assumes the RootComponent of the AttachParent actor.
186 // If that's not the case, we can't update this, as the client wouldn't be able to resolve the Component and would detach as a result.
187 AttachmentWeldReplication.AttachParent = RootComponent->GetAttachParent()->GetAttachmentRootActor();
188 if (AttachmentWeldReplication.AttachParent != nullptr)
189 {
190 AttachmentWeldReplication.LocationOffset = RootComponent->GetRelativeLocation();
191 AttachmentWeldReplication.RotationOffset = RootComponent->GetRelativeRotation();
192 AttachmentWeldReplication.RelativeScale3D = RootComponent->GetRelativeScale3D();
193 AttachmentWeldReplication.AttachComponent = RootComponent->GetAttachParent();
194 AttachmentWeldReplication.AttachSocket = RootComponent->GetAttachSocketName();
195 AttachmentWeldReplication.bIsWelded = RootPrimComp ? RootPrimComp->IsWelded() : false;
196
197 // Technically, the values might have stayed the same, but we'll just assume they've changed.
198 bWasAttachmentModified = true;
199 }
200 }
201 else
202 {
203 RepMovement.Location = FRepMovement::RebaseOntoZeroOrigin(RootComponent->GetComponentLocation(), this);
204 RepMovement.Rotation = RootComponent->GetComponentRotation();
205 RepMovement.LinearVelocity = GetVelocity();
206 RepMovement.AngularVelocity = FVector::ZeroVector;
207
208 // Technically, the values might have stayed the same, but we'll just assume they've changed.
209 bWasRepMovementModified = true;
210 }
211
212 bWasRepMovementModified = (bWasRepMovementModified || RepMovement.bRepPhysics);
213 RepMovement.bRepPhysics = false;
214 }
215#if WITH_PUSH_MODEL
216 if (bWasRepMovementModified)
217 {
218 //MARK_PROPERTY_DIRTY_FROM_NAME(AActor, ReplicatedMovement, this);
219 }
220
221 if (bWasAttachmentModified ||
222 OldAttachParent != AttachmentWeldReplication.AttachParent ||
223 OldAttachComponent != AttachmentWeldReplication.AttachComponent)
224 {
225 //MARK_PROPERTY_DIRTY_FROM_NAME(AGrippableSkeletalMeshActor, AttachmentWeldReplication, this);
226 }
227#endif
228 }
229}
230
231bool AGrippableSkeletalMeshActor::ReplicateSubobjects(UActorChannel* Channel, class FOutBunch* Bunch, FReplicationFlags* RepFlags)
232{
233 bool WroteSomething = Super::ReplicateSubobjects(Channel, Bunch, RepFlags);
234
236 {
237 for (UVRGripScriptBase* Script : GripLogicScripts)
238 {
239 if (Script && !Script->IsPendingKill())
240 {
241 WroteSomething |= Channel->ReplicateSubobject(Script, *Bunch, *RepFlags);
242 }
243 }
244 }
245
246 return WroteSomething;
247}
248
249/*void AGrippableSkeletalMeshActor::GetLifetimeReplicatedProps(TArray< class FLifetimeProperty > & OutLifetimeProps) const
250{
251 DOREPLIFETIME(AGrippableSkeletalMeshActor, VRGripInterfaceSettings);
252}*/
253
254//=============================================================================
258
260{
261 // Call the base class
262 Super::BeginPlay();
263
264 // Call all grip scripts begin play events so they can perform any needed logic
265 for (UVRGripScriptBase* Script : GripLogicScripts)
266 {
267 if (Script)
268 {
269 Script->BeginPlay(this);
270 }
271 }
272}
273
275{
277}
278
283
286void AGrippableSkeletalMeshActor::OnGripRelease_Implementation(UGripMotionControllerComponent* ReleasingController, const FBPActorGripInformation& GripInformation, bool bWasSocketed) { }
289void AGrippableSkeletalMeshActor::OnSecondaryGrip_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* SecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripAdded.Broadcast(GripOwningController, GripInformation); }
290void AGrippableSkeletalMeshActor::OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent* GripOwningController, USceneComponent* ReleasingSecondaryGripComponent, const FBPActorGripInformation& GripInformation) { OnSecondaryGripRemoved.Broadcast(GripOwningController, GripInformation); }
295void AGrippableSkeletalMeshActor::OnInput_Implementation(FKey Key, EInputEvent KeyEvent) {}
296bool AGrippableSkeletalMeshActor::RequestsSocketing_Implementation(USceneComponent*& ParentToSocketTo, FName& OptionalSocketName, FTransform_NetQuantize& RelativeTransform) { return false; }
297
302
303
308
313
318
323
328
333
334void AGrippableSkeletalMeshActor::GetGripStiffnessAndDamping_Implementation(float& GripStiffnessOut, float& GripDampingOut)
335{
338}
339
344
349
350void AGrippableSkeletalMeshActor::ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool& bHadSlotInRange, FTransform& SlotWorldTransform, FName& SlotName, UGripMotionControllerComponent* CallingController, FName OverridePrefix)
351{
352 if (OverridePrefix.IsNone())
353 bSecondarySlot ? OverridePrefix = "VRGripS" : OverridePrefix = "VRGripP";
354
355 UVRExpansionFunctionLibrary::GetGripSlotInRangeByTypeName(OverridePrefix, this, WorldLocation, bSecondarySlot ? VRGripInterfaceSettings.SecondarySlotRange : VRGripInterfaceSettings.PrimarySlotRange, bHadSlotInRange, SlotWorldTransform, SlotName, CallingController);
356}
357
362
363void AGrippableSkeletalMeshActor::IsHeld_Implementation(TArray<FBPGripPair>& HoldingControllers, bool& bIsHeld)
364{
365 HoldingControllers = VRGripInterfaceSettings.HoldingControllers;
367}
368
370{
372 {
373 // The subsystem automatically removes entries with the same function signature so its safe to just always add here
374 GetWorld()->GetSubsystem<UBucketUpdateSubsystem>()->AddObjectToBucket(ClientAuthReplicationData.UpdateRate, this, FName(TEXT("PollReplicationEvent")));
376
377 if (UWorld* World = GetWorld())
378 ClientAuthReplicationData.TimeAtInitialThrow = World->GetTimeSeconds();
379
380 return true;
381 }
382
383 return false;
384}
385
387{
389 {
390 GetWorld()->GetSubsystem<UBucketUpdateSubsystem>()->RemoveObjectFromBucketByFunctionName(this, FName(TEXT("PollReplicationEvent")));
392 return true;
393 }
394
395 return false;
396}
397
399{
400 if (bGripped)
401 {
402 OnGripped.Broadcast(Controller, GripInformation);
403 }
404 else
405 {
406 OnDropped.Broadcast(Controller, GripInformation, bWasSocketed);
407 }
408}
409
411{
412 if (bIsHeld)
413 {
414 VRGripInterfaceSettings.HoldingControllers.AddUnique(FBPGripPair(HoldingController, GripID));
416
419 }
420 else
421 {
422 VRGripInterfaceSettings.HoldingControllers.Remove(FBPGripPair(HoldingController, GripID));
424
426 {
427 bool bWasLocallyOwned = HoldingController ? HoldingController->IsLocallyControlled() : false;
428 if (bWasLocallyOwned && ShouldWeSkipAttachmentReplication(false))
429 {
430 if (UPrimitiveComponent* PrimComp = Cast<UPrimitiveComponent>(GetRootComponent()))
431 {
432 if (PrimComp->IsSimulatingPhysics())
433 {
435 }
436 }
437 }
438 }
439 }
440}
441
442/*FBPInteractionSettings AGrippableSkeletalMeshActor::GetInteractionSettings_Implementation()
443{
444 return VRGripInterfaceSettings.InteractionSettings;
445}*/
446
447bool AGrippableSkeletalMeshActor::GetGripScripts_Implementation(TArray<UVRGripScriptBase*>& ArrayReference)
448{
449 ArrayReference = GripLogicScripts;
450 return GripLogicScripts.Num() > 0;
451}
452
454{
456 return false; // Tell the bucket subsystem to remove us from consideration
457
458 UWorld* OurWorld = GetWorld();
459 if (!OurWorld)
460 return false; // Tell the bucket subsystem to remove us from consideration
461
462 bool bRemoveBlocking = false;
463
464 if ((OurWorld->GetTimeSeconds() - ClientAuthReplicationData.TimeAtInitialThrow) > 10.0f)
465 {
466 // Lets time out sending, its been 10 seconds since we threw the object and its likely that it is conflicting with some server
467 // Authed movement that is forcing it to keep momentum.
468 //return false; // Tell the bucket subsystem to remove us from consideration
469 bRemoveBlocking = true;
470 }
471
472 // Store current transform for resting check
473 FTransform CurTransform = this->GetActorTransform();
474
475 if (!bRemoveBlocking)
476 {
477 if (!CurTransform.GetRotation().Equals(ClientAuthReplicationData.LastActorTransform.GetRotation()) || !CurTransform.GetLocation().Equals(ClientAuthReplicationData.LastActorTransform.GetLocation()))
478 {
480
481 if (UPrimitiveComponent* PrimComp = Cast<UPrimitiveComponent>(RootComponent))
482 {
483 // Need to clamp to a max time since start, to handle cases with conflicting collisions
484 if (PrimComp->IsSimulatingPhysics() && ShouldWeSkipAttachmentReplication(false))
485 {
486 FRepMovementVR ClientAuthMovementRep;
487 if (ClientAuthMovementRep.GatherActorsMovement(this))
488 {
489 Server_GetClientAuthReplication(ClientAuthMovementRep);
490
491 if (PrimComp->RigidBodyIsAwake())
492 {
493 return true;
494 }
495 }
496 }
497 }
498 else
499 {
500 bRemoveBlocking = true;
501 //return false; // Tell the bucket subsystem to remove us from consideration
502 }
503 }
504 //else
505 // {
506 // Difference is too small, lets end sending location
507 //ClientAuthReplicationData.LastActorTransform = FTransform::Identity;
508 // }
509 }
510
511 bool TimedBlockingRelease = false;
512
513 AActor* TopOwner = GetOwner();
514 if (TopOwner != nullptr)
515 {
516 AActor* tempOwner = TopOwner->GetOwner();
517
518 // I have an owner so search that for the top owner
519 while (tempOwner)
520 {
521 TopOwner = tempOwner;
522 tempOwner = TopOwner->GetOwner();
523 }
524
525 if (APlayerController* PlayerController = Cast<APlayerController>(TopOwner))
526 {
527 if (APlayerState* PlayerState = PlayerController->PlayerState)
528 {
530 {
531 OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle);
532 }
533
534 // Lets clamp the ping to a min / max value just in case
535 float clampedPing = FMath::Clamp(PlayerState->ExactPing * 0.001f, 0.0f, 1000.0f);
536 OurWorld->GetTimerManager().SetTimer(ClientAuthReplicationData.ResetReplicationHandle, this, &AGrippableSkeletalMeshActor::CeaseReplicationBlocking, clampedPing, false);
537 TimedBlockingRelease = true;
538 }
539 }
540 }
541
542 if (!TimedBlockingRelease)
543 {
545 }
546
547 // Tell server to kill us
549 return false; // Tell the bucket subsystem to remove us from consideration
550}
551
553{
556
557 ClientAuthReplicationData.LastActorTransform = FTransform::Identity;
558
560 {
561 if (UWorld* OurWorld = GetWorld())
562 {
563 OurWorld->GetTimerManager().ClearTimer(ClientAuthReplicationData.ResetReplicationHandle);
564 }
565 }
566}
567
568void AGrippableSkeletalMeshActor::EndPlay(const EEndPlayReason::Type EndPlayReason)
569{
571
572 // Call all grip scripts begin play events so they can perform any needed logic
573 for (UVRGripScriptBase* Script : GripLogicScripts)
574 {
575 if (Script)
576 {
577 Script->EndPlay(EndPlayReason);
578 }
579 }
580
581 Super::EndPlay(EndPlayReason);
582}
583
584bool AGrippableSkeletalMeshActor::Server_EndClientAuthReplication_Validate()
585{
586 return true;
587}
588
589void AGrippableSkeletalMeshActor::Server_EndClientAuthReplication_Implementation()
590{
591 if (UWorld* World = GetWorld())
592 {
593 if (FPhysScene* PhysScene = World->GetPhysicsScene())
594 {
595 if (FPhysicsReplication* PhysicsReplication = PhysScene->GetPhysicsReplication())
596 {
597 PhysicsReplication->RemoveReplicatedTarget(this->GetSkeletalMeshComponent());
598 }
599 }
600 }
601}
602
603bool AGrippableSkeletalMeshActor::Server_GetClientAuthReplication_Validate(const FRepMovementVR& newMovement)
604{
605 return true;
606}
607
608void AGrippableSkeletalMeshActor::Server_GetClientAuthReplication_Implementation(const FRepMovementVR& newMovement)
609{
611 {
612 if (!newMovement.Location.ContainsNaN() && !newMovement.Rotation.ContainsNaN())
613 {
614 FRepMovement& MovementRep = GetReplicatedMovement_Mutable();
615 newMovement.CopyTo(MovementRep);
617 }
618 }
619}
620
622{
624 //if (bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication())
625 {
626 return;
627 }
628
629 if (AttachmentWeldReplication.AttachParent)
630 {
631 if (RootComponent)
632 {
633 USceneComponent* AttachParentComponent = (AttachmentWeldReplication.AttachComponent ? AttachmentWeldReplication.AttachComponent : AttachmentWeldReplication.AttachParent->GetRootComponent());
634
635 if (AttachParentComponent)
636 {
637 RootComponent->SetRelativeLocation_Direct(AttachmentWeldReplication.LocationOffset);
638 RootComponent->SetRelativeRotation_Direct(AttachmentWeldReplication.RotationOffset);
639 RootComponent->SetRelativeScale3D_Direct(AttachmentWeldReplication.RelativeScale3D);
640
641 // If we're already attached to the correct Parent and Socket, then the update must be position only.
642 // AttachToComponent would early out in this case.
643 // Note, we ignore the special case for simulated bodies in AttachToComponent as AttachmentReplication shouldn't get updated
644 // if the body is simulated (see AActor::GatherMovement).
645 const bool bAlreadyAttached = (AttachParentComponent == RootComponent->GetAttachParent() && AttachmentWeldReplication.AttachSocket == RootComponent->GetAttachSocketName() && AttachParentComponent->GetAttachChildren().Contains(RootComponent));
646 if (bAlreadyAttached)
647 {
648 // Note, this doesn't match AttachToComponent, but we're assuming it's safe to skip physics (see comment above).
649 RootComponent->UpdateComponentToWorld(EUpdateTransformFlags::SkipPhysicsUpdate, ETeleportType::None);
650 }
651 else
652 {
653 FAttachmentTransformRules attachRules = FAttachmentTransformRules::KeepRelativeTransform;
654 attachRules.bWeldSimulatedBodies = AttachmentWeldReplication.bIsWelded;
655 RootComponent->AttachToComponent(AttachParentComponent, attachRules, AttachmentWeldReplication.AttachSocket);
656 }
657 }
658 }
659 }
660 else
661 {
662 DetachFromActor(FDetachmentTransformRules::KeepWorldTransform);
663
664 // Handle the case where an object was both detached and moved on the server in the same frame.
665 // Calling this extraneously does not hurt but will properly fire events if the movement state changed while attached.
666 // This is needed because client side movement is ignored when attached
667 if (IsReplicatingMovement())
668 {
670 }
671 }
672}
673
675{
677 //if (bAllowIgnoringAttachOnOwner && (ClientAuthReplicationData.bIsCurrentlyClientAuth || ShouldWeSkipAttachmentReplication()))
678 {
679 return;
680 }
681
682 if (RootComponent)
683 {
684 const FRepAttachment ReplicationAttachment = GetAttachmentReplication();
685 if (!ReplicationAttachment.AttachParent)
686 {
687 const FRepMovement& RepMove = GetReplicatedMovement();
688
689 // This "fix" corrects the simulation state not replicating over correctly
690 // If you turn off movement replication, simulate an object, turn movement replication back on and un-simulate, it never knows the difference
691 // This change ensures that it is checking against the current state
692 if (RootComponent->IsSimulatingPhysics() != RepMove.bRepPhysics)//SavedbRepPhysics != ReplicatedMovement.bRepPhysics)
693 {
694 // Turn on/off physics sim to match server.
695 SyncReplicatedPhysicsSimulation();
696
697 // It doesn't really hurt to run it here, the super can call it again but it will fail out as they already match
698 }
699 }
700 }
701
702 Super::OnRep_ReplicateMovement();
703}
704
706{
708 //if (ClientAuthReplicationData.bIsCurrentlyClientAuth && ShouldWeSkipAttachmentReplication(false))
709 {
710 return;
711 }
712
713 Super::OnRep_ReplicatedMovement();
714}
715
717{
719 //if ((ClientAuthReplicationData.bIsCurrentlyClientAuth || VRGripInterfaceSettings.bIsHeld) && bAllowIgnoringAttachOnOwner && ShouldWeSkipAttachmentReplication(false))
720 {
721 return;
722 }
723
724 Super::PostNetReceivePhysicState();
725}
726
728{
729 Super::MarkComponentsAsPendingKill();
730
731 for (int32 i = 0; i < GripLogicScripts.Num(); ++i)
732 {
733 if (UObject* SubObject = GripLogicScripts[i])
734 {
735 SubObject->MarkPendingKill();
736 }
737 }
738
739 GripLogicScripts.Empty();
740}
741
743{
744 Super::PreDestroyFromReplication();
745
746 // Destroy any sub-objects we created
747 for (int32 i = 0; i < GripLogicScripts.Num(); ++i)
748 {
749 if (UObject* SubObject = GripLogicScripts[i])
750 {
751 OnSubobjectDestroyFromReplication(SubObject); //-V595
752 SubObject->PreDestroyFromReplication();
753 SubObject->MarkPendingKill();
754 }
755 }
756
757 for (UActorComponent* ActorComp : GetComponents())
758 {
759 // Pending kill components should have already had this called as they were network spawned and are being killed
760 if (ActorComp && !ActorComp->IsPendingKill() && ActorComp->GetClass()->ImplementsInterface(UVRGripInterface::StaticClass()))
761 ActorComp->PreDestroyFromReplication();
762 }
763
764 GripLogicScripts.Empty();
765}
766
768{
769 Super::BeginDestroy();
770
771 for (int32 i = 0; i < GripLogicScripts.Num(); i++)
772 {
773 if (UObject* SubObject = GripLogicScripts[i])
774 {
775 SubObject->MarkPendingKill();
776 }
777 }
778
779 GripLogicScripts.Empty();
780}
781
783{
784 Super::GetSubobjectsWithStableNamesForNetworking(ObjList);
785
787 {
788 for (int32 i = 0; i < GripLogicScripts.Num(); ++i)
789 {
790 if (UObject* SubObject = GripLogicScripts[i])
791 {
792 ObjList.Add(SubObject);
793 }
794 }
795 }
796}
EGripMovementReplicationSettings
UENUM(Blueprintable)
ESecondaryGripType
UENUM(Blueprintable)
EGripCollisionType
UENUM(Blueprintable)
EGripLateUpdateSettings
UENUM(Blueprintable)
EGripInterfaceTeleportBehavior
UENUM(Blueprintable)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPl...
virtual void OnEndUsed_Implementation() override
virtual void IsHeld_Implementation(TArray< FBPGripPair > &HoldingControllers, bool &bIsHeld) override
FVROnGripSignature OnSecondaryGripAdded
UPROPERTY(BlueprintAssignable, Category = "Grip Events")
virtual bool GetGripScripts_Implementation(TArray< UVRGripScriptBase * > &ArrayReference) override
virtual void SetHeld_Implementation(UGripMotionControllerComponent *HoldingController, uint8 GripID, bool bIsHeld) override
void Server_GetClientAuthReplication(const FRepMovementVR &newMovement)
UFUNCTION(UnReliable, Server, WithValidation, Category = "Networking")
virtual void OnRep_AttachmentReplication() override
virtual void Native_NotifyThrowGripDelegates(UGripMotionControllerComponent *Controller, bool bGripped, const FBPActorGripInformation &GripInformation, bool bWasSocketed=false) override
virtual void OnEndSecondaryUsed_Implementation() override
bool ReplicateSubobjects(UActorChannel *Channel, class FOutBunch *Bunch, FReplicationFlags *RepFlags) override
FRepAttachmentWithWeld AttachmentWeldReplication
UPROPERTY(Replicated, ReplicatedUsing = OnRep_AttachmentReplication)
virtual EGripCollisionType GetPrimaryGripType_Implementation(bool bIsSlot) override
virtual void OnChildGrip_Implementation(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation) override
void SetGripPriority(int NewGripPriority)
UFUNCTION(BlueprintCallable, Category = "VRGripInterface")
void SetDenyGripping(bool bDenyGripping)
UFUNCTION(BlueprintCallable, Category = "VRGripInterface")
virtual ESecondaryGripType SecondaryGripType_Implementation() override
virtual EGripLateUpdateSettings GripLateUpdateSetting_Implementation() override
bool RemoveFromClientReplicationBucket()
UFUNCTION(BlueprintCallable, Category = "Networking")
virtual EGripInterfaceTeleportBehavior TeleportBehavior_Implementation() override
FBPInterfaceProperties VRGripInterfaceSettings
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
virtual void ClosestGripSlotInRange_Implementation(FVector WorldLocation, bool bSecondarySlot, bool &bHadSlotInRange, FTransform &SlotWorldTransform, FName &SlotName, UGripMotionControllerComponent *CallingController=nullptr, FName OverridePrefix=NAME_None) override
bool bReplicateGripScripts
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
virtual float GripBreakDistance_Implementation() override
AGrippableSkeletalMeshActor(const FObjectInitializer &ObjectInitializer)
virtual bool RequestsSocketing_Implementation(USceneComponent *&ParentToSocketTo, FName &OptionalSocketName, FTransform_NetQuantize &RelativeTransform) override
virtual void OnGrip_Implementation(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation) override
virtual void OnRep_ReplicateMovement() override
virtual EGripMovementReplicationSettings GripMovementReplicationType_Implementation() override
virtual void TickGrip_Implementation(UGripMotionControllerComponent *GrippingController, const FBPActorGripInformation &GripInformation, float DeltaTime) override
bool AddToClientReplicationBucket()
UFUNCTION(BlueprintCallable, Category = "Networking")
FVROnGripSignature OnGripped
UPROPERTY(BlueprintAssignable, Category = "Grip Events")
virtual bool DenyGripping_Implementation(UGripMotionControllerComponent *GripInitiator=nullptr) override
virtual void MarkComponentsAsPendingKill() override
virtual void OnSecondaryUsed_Implementation() override
virtual void OnChildGripRelease_Implementation(UGripMotionControllerComponent *ReleasingController, const FBPActorGripInformation &GripInformation, bool bWasSocketed=false) override
void Server_EndClientAuthReplication()
UFUNCTION(Reliable, Server, WithValidation, Category = "Networking")
virtual void PreReplication(IRepChangedPropertyTracker &ChangedPropertyTracker) override
virtual void PostNetReceivePhysicState() override
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
virtual bool AllowsMultipleGrips_Implementation() override
virtual void OnGripRelease_Implementation(UGripMotionControllerComponent *ReleasingController, const FBPActorGripInformation &GripInformation, bool bWasSocketed=false) override
bool bAllowIgnoringAttachOnOwner
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
virtual void OnSecondaryGripRelease_Implementation(UGripMotionControllerComponent *GripOwningController, USceneComponent *ReleasingSecondaryGripComponent, const FBPActorGripInformation &GripInformation) override
virtual FBPAdvGripSettings AdvancedGripSettings_Implementation() override
virtual void GetSubobjectsWithStableNamesForNetworking(TArray< UObject * > &ObjList) override
virtual void OnRep_ReplicatedMovement() override
void CeaseReplicationBlocking()
UFUNCTION(Category = "Networking")
FGameplayTagContainer GameplayTags
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "GameplayTags")
virtual void PreDestroyFromReplication() override
FVROnGripSignature OnSecondaryGripRemoved
UPROPERTY(BlueprintAssignable, Category = "Grip Events")
FVRClientAuthReplicationData ClientAuthReplicationData
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Replication")
bool bRepGripSettingsAndGameplayTags
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "VRGripInterface")
virtual void OnSecondaryGrip_Implementation(UGripMotionControllerComponent *GripOwningController, USceneComponent *SecondaryGripComponent, const FBPActorGripInformation &GripInformation) override
bool ShouldWeSkipAttachmentReplication(bool bConsiderHeld=true) const
TArray< class UVRGripScriptBase * > GripLogicScripts
UPROPERTY(EditAnywhere, Replicated, BlueprintReadOnly, Instanced, Category = "VRGripInterface")
virtual void OnInput_Implementation(FKey Key, EInputEvent KeyEvent) override
virtual void GetGripStiffnessAndDamping_Implementation(float &GripStiffnessOut, float &GripDampingOut) override
virtual bool SimulateOnDrop_Implementation() override
virtual void GatherCurrentMovement() override
virtual void OnUsed_Implementation() override
FVROnDropSignature OnDropped
UPROPERTY(BlueprintAssignable, Category = "Grip Events")
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent), ClassGroup = MotionController)
UCLASS(Blueprintable, meta = (BlueprintSpawnableComponent, ChildCanTick), ClassGroup = (VRExpansionPl...
UOptionalRepSkeletalMeshComponent(const FObjectInitializer &ObjectInitializer)
virtual void PreReplication(IRepChangedPropertyTracker &ChangedPropertyTracker) override
bool bReplicateMovement
UPROPERTY(EditAnywhere, Replicated, BlueprintReadWrite, Category = "Component Replication")
static void GetGripSlotInRangeByTypeName(FName SlotType, AActor *Actor, FVector WorldLocation, float MaxRange, bool &bHadSlotInRange, FTransform &SlotWorldTransform, FName &SlotName, UGripMotionControllerComponent *QueryController=nullptr)
UFUNCTION(BlueprintPure, Category = "VRGrip", meta = (bIgnoreSelf = "true", DisplayName = "GetGripSlo...
UCLASS(NotBlueprintable, BlueprintType, EditInlineNew, DefaultToInstanced, Abstract,...
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
uint8 GripPriority
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "AdvancedGripSettings")
USTRUCT(BlueprintType, Category = "VRExpansionLibrary")
ESecondaryGripType SecondaryGripType
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
bool bDenyGripping
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
EGripCollisionType FreeDefaultGripType
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
float ConstraintBreakDistance
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
bool bAllowMultipleGrips
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
float SecondarySlotRange
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
EGripLateUpdateSettings LateUpdateSetting
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
EGripCollisionType SlotDefaultGripType
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
EGripInterfaceTeleportBehavior OnTeleportBehavior
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
float ConstraintStiffness
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
float PrimarySlotRange
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
bool bIsHeld
UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "VRGripInterface")
TArray< FBPGripPair > HoldingControllers
UPROPERTY(BlueprintReadWrite, NotReplicated, Category = "VRGripInterface")
float ConstraintDamping
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
FBPAdvGripSettings AdvancedGripSettings
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface|AdvancedGripSettings")
EGripMovementReplicationSettings MovementReplicationType
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
bool bSimulateOnDrop
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRGripInterface")
void CopyTo(FRepMovement &other) const
bool GatherActorsMovement(AActor *OwningActor)
USTRUCT(BlueprintType, Category = "VRExpansionLibrary|TransformNetQuantize", meta = (HasNativeMake = ...
int32 UpdateRate
UPROPERTY(EditAnywhere, NotReplicated, BlueprintReadOnly, Category = "VRReplication",...
bool bUseClientAuthThrowing
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "VRReplication")