@@ -359,6 +359,7 @@ namespace {
359
359
}
360
360
361
361
UPrefabricatorAsset* PrefabAsset = Cast<UPrefabricatorAsset>(PrefabActor->PrefabComponent ->PrefabAssetInterface .LoadSynchronous ());
362
+ USceneComponent* SceneComponent = Cast<USceneComponent>(ObjToSerialize);
362
363
363
364
if (!PrefabAsset) {
364
365
return ;
@@ -531,12 +532,28 @@ void FPrefabTools::LoadActorState(AActor* InActor, const FPrefabricatorActorData
531
532
for (const FPrefabricatorComponentData& ComponentData : InActorData.Components ) {
532
533
if (UActorComponent** SearchResult = ComponentsByName.Find (ComponentData.ComponentName )) {
533
534
UActorComponent* Component = *SearchResult;
535
+ USceneComponent* SceneComponent = Cast<USceneComponent>(Component);
536
+
537
+ // JB: We store the world location in case we would be restoring a component simulating physics.
538
+ // JB: This is necessary only for prefab spawned at runtime.
539
+ FVector WorldLocation = FVector::ZeroVector;
540
+ if (InActor->HasActorBegunPlay ()) {
541
+ if (SceneComponent)
542
+ {
543
+ WorldLocation = SceneComponent->GetComponentLocation ();
544
+ }
545
+ }
546
+
534
547
bool bPreviouslyRegister;
535
548
{
536
549
// SCOPE_CYCLE_COUNTER(STAT_LoadStateFromPrefabAsset_UnregisterComponent);
537
550
bPreviouslyRegister = Component->IsRegistered ();
538
551
if (InSettings.bUnregisterComponentsBeforeLoading && bPreviouslyRegister) {
539
552
Component->UnregisterComponent ();
553
+ // JB: Some of the components (e.g., UPhysicsConstraintComponent) also require re-initialization.
554
+ if (Component->HasBeenInitialized ()) {
555
+ Component->UninitializeComponent ();
556
+ }
540
557
}
541
558
}
542
559
@@ -548,7 +565,15 @@ void FPrefabTools::LoadActorState(AActor* InActor, const FPrefabricatorActorData
548
565
{
549
566
// SCOPE_CYCLE_COUNTER(STAT_LoadStateFromPrefabAsset_RegisterComponent);
550
567
if (InSettings.bUnregisterComponentsBeforeLoading && bPreviouslyRegister) {
568
+ // JB: Register component will also initialize component if necessary.
551
569
Component->RegisterComponent ();
570
+ // JB: Components that are simulating physics are detached from the actor on register.
571
+ // JB: Restoring their relative location above will cause them to be spawned at a wrong location so we fix it.
572
+ // JB: This is necessary only for prefab spawned at runtime.
573
+ if (InActor->HasActorBegunPlay () && SceneComponent->IsSimulatingPhysics ()) {
574
+ SceneComponent->SetRelativeLocation (WorldLocation);
575
+ }
576
+ int a = 0 ;
552
577
}
553
578
}
554
579
}
@@ -696,7 +721,8 @@ void FPrefabTools::LoadStateFromPrefabAsset(APrefabActor* PrefabActor, const FPr
696
721
}
697
722
698
723
// JB: Spawning actors on top of each other may cause problems with PhysicX (as it needs to compute the overlaps).
699
- ChildActor = Service->SpawnActor (ActorClass, PrefabActor->GetActorTransform (), PrefabActor->GetLevel (), Template);
724
+ FTransform WorldTransform = ActorItemData.RelativeTransform * PrefabActor->GetTransform ();
725
+ ChildActor = Service->SpawnActor (ActorClass, WorldTransform, PrefabActor->GetLevel (), Template);
700
726
if (!Template) {
701
727
LoadActorState (ChildActor, ActorItemData, InSettings);
702
728
if (InState.IsValid ()) {
0 commit comments