bool UActorComponent::Modify( bool bAlwaysMarkDirty/*=true*/ ) { // If this is a construction script component we don't store them in the transaction buffer. Instead, mark // the Actor as modified so that we store of the transaction annotation that has the component properties stashed AActor* MyOwner = GetOwner(); if (MyOwner && IsCreatedByConstructionScript()) { return MyOwner->Modify(bAlwaysMarkDirty); } return Super::Modify(bAlwaysMarkDirty); }
void UActorComponent::DestroyComponent(bool bPromoteChildren/*= false*/) { // Avoid re-entrancy if (bIsBeingDestroyed) { return; } bIsBeingDestroyed = true; if (bHasBegunPlay) { EndPlay(EEndPlayReason::Destroyed); } // Ensure that we call UninitializeComponent before we destroy this component if (bHasBeenInitialized) { UninitializeComponent(); } // Unregister if registered if(IsRegistered()) { UnregisterComponent(); } // Then remove from Components array, if we have an Actor if(AActor* MyOwner = GetOwner()) { if (IsCreatedByConstructionScript()) { MyOwner->BlueprintCreatedComponents.Remove(this); } else { MyOwner->RemoveInstanceComponent(this); } MyOwner->RemoveOwnedComponent(this); if (MyOwner->GetRootComponent() == this) { MyOwner->SetRootComponent(NULL); } } // Tell the component it is being destroyed OnComponentDestroyed(); // Finally mark pending kill, to NULL out any other refs MarkPendingKill(); }
void UChildActorComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) { static const FName NAME_ChildActorClass = GET_MEMBER_NAME_CHECKED(UChildActorComponent, ChildActorClass); if (PropertyChangedEvent.Property && PropertyChangedEvent.Property->GetFName() == NAME_ChildActorClass) { ChildActorName = NAME_None; // If this was created by construction script, the post edit change super call will destroy it anyways if (!IsCreatedByConstructionScript()) { DestroyChildActor(); CreateChildActor(); } } Super::PostEditChangeProperty(PropertyChangedEvent); }
void UChildActorComponent::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) { if (PropertyChangedEvent.Property && PropertyChangedEvent.Property->GetFName() == GET_MEMBER_NAME_CHECKED(UChildActorComponent, ChildActorClass)) { ChildActorName = NAME_None; if (!IsTemplate()) { UChildActorComponent* Archetype = CastChecked<UChildActorComponent>(GetArchetype()); ChildActorTemplate = (Archetype->ChildActorClass == ChildActorClass ? Archetype->ChildActorTemplate : nullptr); } // If this was created by construction script, the post edit change super call will destroy it anyways if (!IsCreatedByConstructionScript()) { DestroyChildActor(); CreateChildActor(); } } Super::PostEditChangeProperty(PropertyChangedEvent); }
void UActorComponent::RegisterComponentWithWorld(UWorld* InWorld) { checkf(!HasAnyFlags(RF_Unreachable), TEXT("%s"), *GetFullName()); if(IsPendingKill()) { UE_LOG(LogActorComponent, Log, TEXT("RegisterComponentWithWorld: (%s) Trying to register component with IsPendingKill() == true. Aborting."), *GetPathName()); return; } // If the component was already registered, do nothing if(IsRegistered()) { UE_LOG(LogActorComponent, Log, TEXT("RegisterComponentWithWorld: (%s) Already registered. Aborting."), *GetPathName()); return; } if(InWorld == NULL) { //UE_LOG(LogActorComponent, Log, TEXT("RegisterComponentWithWorld: (%s) NULL InWorld specified. Aborting."), *GetPathName()); return; } // If not registered, should not have a scene checkf(World == NULL, TEXT("%s"), *GetFullName()); AActor* MyOwner = GetOwner(); checkSlow(MyOwner == nullptr || MyOwner->OwnsComponent(this)); if (MyOwner && MyOwner->GetClass()->HasAnyClassFlags(CLASS_NewerVersionExists)) { UE_LOG(LogActorComponent, Log, TEXT("RegisterComponentWithWorld: Owner belongs to a DEADCLASS")); return; } #if !(UE_BUILD_SHIPPING || UE_BUILD_TEST) // Can only register with an Actor if we are created within one if(MyOwner) { checkf(!MyOwner->HasAnyFlags(RF_Unreachable), TEXT("%s"), *GetFullName()); // can happen with undo because the owner will be restored "next" //checkf(!MyOwner->IsPendingKill(), TEXT("%s"), *GetFullName()); if(InWorld != MyOwner->GetWorld()) { // The only time you should specify a scene that is not Owner->GetWorld() is when you don't have an Actor UE_LOG(LogActorComponent, Log, TEXT("RegisterComponentWithWorld: (%s) Specifying a world, but an Owner Actor found, and InWorld is not GetOwner()->GetWorld()"), *GetPathName()); } } #endif // !(UE_BUILD_SHIPPING || UE_BUILD_TEST) World = InWorld; ExecuteRegisterEvents(); RegisterAllComponentTickFunctions(true); if (MyOwner == nullptr || MyOwner->IsActorInitialized()) { if (!bHasBeenInitialized && bWantsInitializeComponent) { InitializeComponent(); } } if (MyOwner && MyOwner->HasActorBegunPlay()) { if (bWantsBeginPlay) { BeginPlay(); } } // If this is a blueprint created component and it has component children they can miss getting registered in some scenarios if (IsCreatedByConstructionScript()) { TArray<UObject*> Children; GetObjectsWithOuter(this, Children, true, RF_PendingKill); for (UObject* Child : Children) { UActorComponent* ChildComponent = Cast<UActorComponent>(Child); if (ChildComponent && !ChildComponent->IsRegistered()) { ChildComponent->RegisterComponentWithWorld(InWorld); } } } }