UActorComponent* AActor::AddComponent(FName TemplateName, bool bManualAttachment, const FTransform& RelativeTransform, const UObject* ComponentTemplateContext) { UActorComponent* Template = nullptr; UBlueprintGeneratedClass* BlueprintGeneratedClass = Cast<UBlueprintGeneratedClass>((ComponentTemplateContext != nullptr) ? ComponentTemplateContext->GetClass() : GetClass()); while(BlueprintGeneratedClass != nullptr) { Template = BlueprintGeneratedClass->FindComponentTemplateByName(TemplateName); if(nullptr != Template) { break; } BlueprintGeneratedClass = Cast<UBlueprintGeneratedClass>(BlueprintGeneratedClass->GetSuperClass()); } bool bIsSceneComponent = false; UActorComponent* NewActorComp = CreateComponentFromTemplate(Template); if(NewActorComp != nullptr) { // Call function to notify component it has been created NewActorComp->OnComponentCreated(); // The user has the option of doing attachment manually where they have complete control or via the automatic rule // that the first component added becomes the root component, with subsequent components attached to the root. USceneComponent* NewSceneComp = Cast<USceneComponent>(NewActorComp); if(NewSceneComp != nullptr) { if (!bManualAttachment) { if (RootComponent == nullptr) { RootComponent = NewSceneComp; } else { NewSceneComp->AttachTo(RootComponent); } } NewSceneComp->SetRelativeTransform(RelativeTransform); bIsSceneComponent = true; } // Register component, which will create physics/rendering state, now component is in correct position NewActorComp->RegisterComponent(); UWorld* World = GetWorld(); if (!bRunningUserConstructionScript && World && bIsSceneComponent) { UPrimitiveComponent* NewPrimitiveComponent = Cast<UPrimitiveComponent>(NewActorComp); if (NewPrimitiveComponent && ACullDistanceVolume::CanBeAffectedByVolumes(NewPrimitiveComponent)) { World->UpdateCullDistanceVolumes(this, NewPrimitiveComponent); } } } return NewActorComp; }
UActorComponent* AActor::AddComponent(FName TemplateName, bool bManualAttachment, const FTransform& RelativeTransform, const UObject* ComponentTemplateContext) { UActorComponent* Template = NULL; UBlueprintGeneratedClass* BlueprintGeneratedClass = Cast<UBlueprintGeneratedClass>((ComponentTemplateContext != NULL) ? ComponentTemplateContext->GetClass() : GetClass()); while(BlueprintGeneratedClass != NULL) { Template = BlueprintGeneratedClass->FindComponentTemplateByName(TemplateName); if(NULL != Template) { break; } BlueprintGeneratedClass = Cast<UBlueprintGeneratedClass>(BlueprintGeneratedClass->GetSuperClass()); } UActorComponent* NewActorComp = CreateComponentFromTemplate(Template); if(NewActorComp != NULL) { // The user has the option of doing attachment manually where they have complete control or via the automatic rule // that the first component added becomes the root component, with subsequent components attached to the root. USceneComponent* NewSceneComp = Cast<USceneComponent>(NewActorComp); bool bDeferRegisterStaticComponent = false; EComponentMobility::Type OriginalMobility = EComponentMobility::Movable; if(NewSceneComp != NULL) { // Components with Mobility set to EComponentMobility::Static or EComponentMobility::Stationary can't be properly set up in UCS (all changes will be rejected // due to EComponentMobility::Static flag) so we're going to temporarily change the flag and defer the registration until UCS has finished. bDeferRegisterStaticComponent = bRunningUserConstructionScript && NewSceneComp->Mobility != EComponentMobility::Movable; OriginalMobility = NewSceneComp->Mobility; if (bDeferRegisterStaticComponent) { NewSceneComp->Mobility = EComponentMobility::Movable; } if (!bManualAttachment) { if (RootComponent == NULL) { RootComponent = NewSceneComp; } else { NewSceneComp->AttachTo(RootComponent); } } NewSceneComp->SetRelativeTransform(RelativeTransform); } // Call function to notify component it has been created NewActorComp->OnComponentCreated(); if (bDeferRegisterStaticComponent) { // Defer registration until after UCS has completed. FDeferRegisterStaticComponents::Get().DeferStaticComponent(this, NewSceneComp, OriginalMobility); } else { // Register component, which will create physics/rendering state, now component is in correct position NewActorComp->RegisterComponent(); } } return NewActorComp; }