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; }
void UUnrealEdEngine::DrawComponentVisualizersHUD(const FViewport* Viewport, const FSceneView* View, FCanvas* Canvas) { // Iterate over all selected actors for (FSelectionIterator It(GetSelectedActorIterator()); It; ++It) { AActor* Actor = Cast<AActor>(*It); if (Actor != NULL) { // Then iterate over components of that actor TInlineComponentArray<UActorComponent*> Components; Actor->GetComponents(Components); for (int32 CompIdx = 0; CompIdx<Components.Num(); CompIdx++) { UActorComponent* Comp = Components[CompIdx]; if (Comp->IsRegistered()) { // Try and find a visualizer TSharedPtr<FComponentVisualizer> Visualizer = FindComponentVisualizer(Comp->GetClass()); if (Visualizer.IsValid()) { Visualizer->DrawVisualizationHUD(Comp, Viewport, View, Canvas); } } } } } }
void ReattachComponents(const TArray<FString>& Args) { if(Args.Num() != 1) { UE_LOG(LogConsoleResponse, Warning, TEXT("Reattach.Components: missing class name parameter")); return; } UE_LOG(LogConsoleResponse, Display, TEXT("Reattach.Components:")); UClass* Class=NULL; if( ParseObject<UClass>( *Args[0], TEXT("CLASS="), Class, ANY_PACKAGE ) && Class->IsChildOf(UActorComponent::StaticClass()) ) { for( FObjectIterator It(Class); It; ++It ) { UActorComponent* ActorComponent = Cast<UActorComponent>(*It); if( ActorComponent ) { UE_LOG(LogConsoleResponse, Display, TEXT(" Component: %s"), *ActorComponent->GetName()); FComponentReregisterContext Reregister(ActorComponent); } } UE_LOG(LogConsoleResponse, Display, TEXT("")); } else { UE_LOG(LogConsoleResponse, Warning, TEXT("Reattach.Components: No objects with the class name '%s' found"), *Args[0]); } }
PyObject *py_ue_actor_destroy_component(ue_PyUObject * self, PyObject * args) { ue_py_check(self); AActor *actor = ue_get_actor(self); if (!actor) return PyErr_Format(PyExc_Exception, "cannot retrieve Actor from uobject"); PyObject *py_component; if (!PyArg_ParseTuple(args, "O:actor_destroy_component", &py_component)) { return NULL; } UActorComponent *component = ue_py_check_type<UActorComponent>(py_component); if (!component) return PyErr_Format(PyExc_Exception, "argument is not a UActorComponent"); #if ENGINE_MINOR_VERSION >= 17 component->DestroyComponent(); #else actor->K2_DestroyComponent(component); #endif Py_INCREF(Py_None); return Py_None; }
void SGraphPinLiveEditVar::GenerateComboBoxIndexes( TArray< TSharedPtr<int32> >& OutComboBoxIndexes ) { if ( !NodeClass.IsValid() ) return; UClass *InClass = Cast<UClass>(NodeClass.Get()); if ( InClass == NULL ) return; GenerateComboBoxIndexesRecurse( InClass, FString(TEXT("")), OutComboBoxIndexes ); AActor *AsActor = Cast<AActor>(InClass->ClassDefaultObject); if ( AsActor != NULL ) { TArray<UActorComponent*> ActorComponents; AsActor->GetComponents(ActorComponents); for ( TArray<UActorComponent*>::TIterator ComponentIt(ActorComponents); ComponentIt; ++ComponentIt ) { UActorComponent *Component = *ComponentIt; check( Component != NULL ); FString ComponentName = Component->GetName() + FString(TEXT(".")); GenerateComboBoxIndexesRecurse( Component->GetClass(), ComponentName, OutComboBoxIndexes ); } } for (int32 i = 0; i < VariableNameList.Num(); ++i) { TSharedPtr<int32> EnumIdxPtr(new int32(i)); OutComboBoxIndexes.Add(EnumIdxPtr); } }
void FComponentMaterialCategory::OnGetMaterialsForView( IMaterialListBuilder& MaterialList ) { const bool bAllowNullEntries = true; // Iterate over every material on the actors for( FMaterialIterator It( SelectedComponents ); It; ++It ) { int32 MaterialIndex = It.GetMaterialIndex(); UActorComponent* CurrentComponent = It.GetComponent(); if( CurrentComponent ) { UMaterialInterface* Material = It.GetMaterial(); AActor* Actor = CurrentComponent->GetOwner(); // Component materials can be replaced if the component supports material overrides const bool bCanBeReplaced = ( CurrentComponent->IsA( UMeshComponent::StaticClass() ) || CurrentComponent->IsA( UTextRenderComponent::StaticClass() ) || CurrentComponent->IsA( ULandscapeComponent::StaticClass() ) ); // Add the material if we allow null materials to be added or we have a valid material if( bAllowNullEntries || Material ) { MaterialList.AddMaterial( MaterialIndex, Material, bCanBeReplaced ); } } } }
void FSCSEditorViewportClient::Draw(const FSceneView* View, FPrimitiveDrawInterface* PDI) { FEditorViewportClient::Draw(View, PDI); bool bHitTesting = PDI->IsHitTesting(); AActor* PreviewActor = GetPreviewActor(); if(PreviewActor) { if(GUnrealEd != NULL) { TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes(); for (int32 SelectionIndex = 0; SelectionIndex < SelectedNodes.Num(); ++SelectionIndex) { FSCSEditorTreeNodePtrType SelectedNode = SelectedNodes[SelectionIndex]; UActorComponent* Comp = SelectedNode->FindComponentInstanceInActor(PreviewActor); if(Comp != NULL && Comp->IsRegistered()) { // Try and find a visualizer TSharedPtr<FComponentVisualizer> Visualizer = GUnrealEd->FindComponentVisualizer(Comp->GetClass()); if (Visualizer.IsValid()) { Visualizer->DrawVisualization(Comp, View, PDI); } } } } } }
void UUnrealEdEngine::SetActorSelectionFlags (AActor* InActor) { TInlineComponentArray<UActorComponent*> Components; InActor->GetComponents(Components); //for every component in the actor for(int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++) { UActorComponent* Component = Components[ComponentIndex]; if (Component->IsRegistered()) { // If we have a 'child actor' component, want to update its visible selection state UChildActorComponent* ChildActorComponent = Cast<UChildActorComponent>(Component); if(ChildActorComponent != NULL && ChildActorComponent->ChildActor != NULL) { SetActorSelectionFlags(ChildActorComponent->ChildActor); } UPrimitiveComponent* PrimComponent = Cast<UPrimitiveComponent>(Component); if(PrimComponent != NULL && PrimComponent->IsRegistered()) { PrimComponent->PushSelectionToProxy(); } UDecalComponent* DecalComponent = Cast<UDecalComponent>(Component); if(DecalComponent != NULL)// && DecalComponent->IsRegistered()) { DecalComponent->PushSelectionToProxy(); } } } }
UActorComponent* UActorBlueprintLibrary::AttachComponentOfClass(UObject* WorldContextObject, TSubclassOf<UActorComponent> ComponentClass, AActor* Owner, FName ComponentName, USceneComponent* AttachTo, FName SocketName) { if (!Owner) { return nullptr; } UActorComponent* Component = NewObject<UActorComponent>(Owner, *ComponentClass, ComponentName); if (!Component) { return nullptr; } Component->RegisterComponent(); Component->OnComponentCreated(); USceneComponent* SceneComponent = Cast<USceneComponent>(Component); if (SceneComponent) { SceneComponent->SetWorldLocation(Owner->GetActorLocation()); SceneComponent->SetWorldRotation(Owner->GetActorRotation()); USceneComponent* AttachToComponent = AttachTo ? AttachTo : Owner->GetRootComponent(); SceneComponent->AttachToComponent(AttachToComponent, FAttachmentTransformRules::KeepWorldTransform, SocketName); } return Component; }
void FBlueprintCompileReinstancer::ReconstructOwnerInstances(TSubclassOf<UActorComponent> ComponentClass) { if (ComponentClass == nullptr) { return; } TArray<UObject*> ComponentInstances; GetObjectsOfClass(ComponentClass, ComponentInstances, /*bIncludeDerivedClasses =*/false); TSet<AActor*> OwnerInstances; for (UObject* ComponentObj : ComponentInstances) { UActorComponent* Component = CastChecked<UActorComponent>(ComponentObj); if (AActor* OwningActor = Component->GetOwner()) { // we don't just rerun construction here, because we could end up // doing it twice for the same actor (if it had multiple components // of this kind), so we put that off as a secondary pass OwnerInstances.Add(OwningActor); } } for (AActor* ComponentOwner : OwnerInstances) { ComponentOwner->RerunConstructionScripts(); } }
void UComponentDelegateBinding::BindDynamicDelegates(AActor* InInstance) const { for(int32 BindIdx=0; BindIdx<ComponentDelegateBindings.Num(); BindIdx++) { const FBlueprintComponentDelegateBinding& Binding = ComponentDelegateBindings[BindIdx]; // Get the function we want to bind UFunction* FunctionToBind = FindField<UFunction>(InInstance->GetClass(), Binding.FunctionNameToBind); // Get the property that points to the component we want to assign to UObjectProperty* ObjProp = FindField<UObjectProperty>(InInstance->GetClass(), Binding.ComponentPropertyName); // If we have both of those.. if(ObjProp != NULL && FunctionToBind != NULL) { // ..see if there is actually a component assigned UActorComponent* Component = Cast<UActorComponent>(ObjProp->GetObjectPropertyValue_InContainer(InInstance)); if(Component != NULL) { // If there is, find the delegate property on it UMulticastDelegateProperty* DelegateProp = FindField<UMulticastDelegateProperty>(Component->GetClass(), Binding.DelegatePropertyName); if(DelegateProp) { // Found that, finally bind function on the actor to this delegate FMulticastScriptDelegate* TargetDelegate = DelegateProp->GetPropertyValuePtr_InContainer(Component); FScriptDelegate Delegate; Delegate.SetFunctionName(Binding.FunctionNameToBind); Delegate.SetObject(InInstance); TargetDelegate->AddUnique(Delegate); } } } } }
//* Destroys the constructed components. void AActor::DestroyConstructedComponents() { // Remove all existing components TInlineComponentArray<UActorComponent*> PreviouslyAttachedComponents; GetComponents(PreviouslyAttachedComponents); // We need the hierarchy to be torn down in attachment order, so do a quick sort PreviouslyAttachedComponents.Remove(nullptr); PreviouslyAttachedComponents.Sort([](UActorComponent& A, UActorComponent& B) { if (USceneComponent* BSC = Cast<USceneComponent>(&B)) { if (BSC->AttachParent == &A) { return false; } } return true; }); for (UActorComponent* Component : PreviouslyAttachedComponents) { if (Component) { bool bDestroyComponent = false; if (Component->IsCreatedByConstructionScript()) { bDestroyComponent = true; } else { UActorComponent* OuterComponent = Component->GetTypedOuter<UActorComponent>(); while (OuterComponent) { if (OuterComponent->IsCreatedByConstructionScript()) { bDestroyComponent = true; break; } OuterComponent = OuterComponent->GetTypedOuter<UActorComponent>(); } } if (bDestroyComponent) { if (Component == RootComponent) { RootComponent = NULL; } Component->DestroyComponent(); // Rename component to avoid naming conflicts in the case where we rerun the SCS and name the new components the same way. FName const NewBaseName( *(FString::Printf(TEXT("TRASH_%s"), *Component->GetClass()->GetName())) ); FName const NewObjectName = MakeUniqueObjectName(this, GetClass(), NewBaseName); Component->Rename(*NewObjectName.ToString(), this, REN_ForceNoResetLoaders|REN_DontCreateRedirectors|REN_NonTransactional); } } } }
FPreviewScene::~FPreviewScene() { // Stop any audio components playing in this scene if( GEngine && GEngine->GetAudioDevice() ) { GEngine->GetAudioDevice()->Flush( GetWorld(), false ); } // Remove all the attached components for( int32 ComponentIndex = 0; ComponentIndex < Components.Num(); ComponentIndex++ ) { UActorComponent* Component = Components[ ComponentIndex ]; if (bForceAllUsedMipsResident) { // Remove the mip streaming override on the mesh to be removed UMeshComponent* pMesh = Cast<UMeshComponent>(Component); if (pMesh != NULL) { pMesh->SetTextureForceResidentFlag(false); } } Component->UnregisterComponent(); } PreviewWorld->CleanupWorld(); GEngine->DestroyWorldContext(GetWorld()); }
UObject* FBlueprintNativeCodeGenModule::FindReplacedNameAndOuter(UObject* Object, FName& OutName) const { OutName = NAME_None; UObject* Outer = nullptr; UActorComponent* ActorComponent = Cast<UActorComponent>(Object); if (ActorComponent) { //if is child of a BPGC and not child of a CDO UBlueprintGeneratedClass* BPGC = nullptr; for (UObject* OuterObject = ActorComponent->GetOuter(); OuterObject && !BPGC; OuterObject = OuterObject->GetOuter()) { if (OuterObject->HasAnyFlags(RF_ClassDefaultObject)) { return Outer; } BPGC = Cast<UBlueprintGeneratedClass>(OuterObject); } for (UBlueprintGeneratedClass* SuperBPGC = BPGC; SuperBPGC && (OutName == NAME_None); SuperBPGC = Cast<UBlueprintGeneratedClass>(SuperBPGC->GetSuperClass())) { if (SuperBPGC->InheritableComponentHandler) { FComponentKey FoundKey = SuperBPGC->InheritableComponentHandler->FindKey(ActorComponent); if (FoundKey.IsValid()) { OutName = FoundKey.IsSCSKey() ? FoundKey.GetSCSVariableName() : ActorComponent->GetFName(); Outer = BPGC->GetDefaultObject(false); break; } } if (SuperBPGC->SimpleConstructionScript) { for (auto Node : SuperBPGC->SimpleConstructionScript->GetAllNodes()) { if (Node->ComponentTemplate == ActorComponent) { OutName = Node->VariableName; if (OutName != NAME_None) { Outer = BPGC->GetDefaultObject(false); break; } } } } } } if (Outer && (EReplacementResult::ReplaceCompletely == IsTargetedForReplacement(Object->GetClass()))) { UE_LOG(LogBlueprintCodeGen, Log, TEXT("Object '%s' has replaced name '%s' and outer: '%s'"), *GetPathNameSafe(Object), *OutName.ToString(), *GetPathNameSafe(Outer)); return Outer; } return nullptr; }
void AActor::CheckForErrors() { if ( GetClass()->HasAnyClassFlags(CLASS_Deprecated) ) { FFormatNamedArguments Arguments; Arguments.Add(TEXT("ActorName"), FText::FromString(GetName())); FMessageLog("MapCheck").Warning() ->AddToken(FUObjectToken::Create(this)) ->AddToken(FTextToken::Create(FText::Format(LOCTEXT( "MapCheck_Message_ActorIsObselete_Deprecated", "{ActorName} : Obsolete and must be removed! (Class is deprecated)" ), Arguments) )) ->AddToken(FMapErrorToken::Create(FMapErrors::ActorIsObselete)); return; } if ( GetClass()->HasAnyClassFlags(CLASS_Abstract) ) { FFormatNamedArguments Arguments; Arguments.Add(TEXT("ActorName"), FText::FromString(GetName())); FMessageLog("MapCheck").Warning() ->AddToken(FUObjectToken::Create(this)) ->AddToken(FTextToken::Create(FText::Format(LOCTEXT( "MapCheck_Message_ActorIsObselete_Abstract", "{ActorName} : Obsolete and must be removed! (Class is abstract)" ), Arguments) )) ->AddToken(FMapErrorToken::Create(FMapErrors::ActorIsObselete)); return; } UPrimitiveComponent* PrimComp = Cast<UPrimitiveComponent>(RootComponent); if( PrimComp && (PrimComp->Mobility != EComponentMobility::Movable) && PrimComp->BodyInstance.bSimulatePhysics) { FFormatNamedArguments Arguments; Arguments.Add(TEXT("ActorName"), FText::FromString(GetName())); FMessageLog("MapCheck").Warning() ->AddToken(FUObjectToken::Create(this)) ->AddToken(FTextToken::Create(FText::Format(LOCTEXT( "MapCheck_Message_StaticPhysNone", "{ActorName} : Static object with bSimulatePhysics set to true" ), Arguments) )) ->AddToken(FMapErrorToken::Create(FMapErrors::StaticPhysNone)); } if( RootComponent && FMath::IsNearlyZero( GetRootComponent()->RelativeScale3D.X * GetRootComponent()->RelativeScale3D.Y * GetRootComponent()->RelativeScale3D.Z ) ) { FFormatNamedArguments Arguments; Arguments.Add(TEXT("ActorName"), FText::FromString(GetName())); FMessageLog("MapCheck").Error() ->AddToken(FUObjectToken::Create(this)) ->AddToken(FTextToken::Create(FText::Format(LOCTEXT( "MapCheck_Message_InvalidDrawscale", "{ActorName} : Invalid DrawScale/DrawScale3D" ), Arguments) )) ->AddToken(FMapErrorToken::Create(FMapErrors::InvalidDrawscale)); } // Route error checking to components. TInlineComponentArray<UActorComponent*> Components; GetComponents(Components); for ( int32 ComponentIndex = 0 ; ComponentIndex < Components.Num() ; ++ComponentIndex ) { UActorComponent* ActorComponent = Components[ ComponentIndex ]; if (ActorComponent->IsRegistered()) { ActorComponent->CheckForErrors(); } } }
UActorComponent* FComponentEditorUtils::DuplicateComponent(UActorComponent* TemplateComponent) { check(TemplateComponent); UActorComponent* NewCloneComponent = nullptr; AActor* Actor = TemplateComponent->GetOwner(); if (!TemplateComponent->IsEditorOnly() && Actor) { Actor->Modify(); UClass* ComponentClass = TemplateComponent->GetClass(); FName NewComponentName = *FComponentEditorUtils::GenerateValidVariableName(ComponentClass, Actor); bool bKeepWorldLocationOnAttach = false; const bool bTemplateTransactional = TemplateComponent->HasAllFlags(RF_Transactional); TemplateComponent->SetFlags(RF_Transactional); NewCloneComponent = DuplicateObject<UActorComponent>(TemplateComponent, Actor, NewComponentName ); if (!bTemplateTransactional) { TemplateComponent->ClearFlags(RF_Transactional); } USceneComponent* NewSceneComponent = Cast<USceneComponent>(NewCloneComponent); if (NewSceneComponent) { // Ensure the clone doesn't think it has children NewSceneComponent->AttachChildren.Empty(); // If the clone is a scene component without an attach parent, attach it to the root (can happen when duplicating the root component) if (!NewSceneComponent->GetAttachParent()) { USceneComponent* RootComponent = Actor->GetRootComponent(); check(RootComponent); // ComponentToWorld is not a UPROPERTY, so make sure the clone has calculated it properly before attachment NewSceneComponent->UpdateComponentToWorld(); NewSceneComponent->AttachTo(RootComponent, NAME_None, EAttachLocation::KeepWorldPosition); } } NewCloneComponent->OnComponentCreated(); // Add to SerializedComponents array so it gets saved Actor->AddInstanceComponent(NewCloneComponent); // Register the new component NewCloneComponent->RegisterComponent(); // Rerun construction scripts Actor->RerunConstructionScripts(); } return NewCloneComponent; }
void UK2Node_AddComponent::ValidateNodeDuringCompilation(FCompilerResultsLog& MessageLog) const { Super::ValidateNodeDuringCompilation(MessageLog); UActorComponent* Template = GetTemplateFromNode(); if (Template) { UClass* TemplateClass = Template->GetClass(); if (!TemplateClass->IsChildOf(UActorComponent::StaticClass()) || TemplateClass->HasAnyClassFlags(CLASS_Abstract) || !TemplateClass->HasMetaData(FBlueprintMetadata::MD_BlueprintSpawnableComponent) ) { FFormatNamedArguments Args; Args.Add(TEXT("TemplateClass"), FText::FromString(TemplateClass->GetName())); Args.Add(TEXT("NodeTitle"), GetNodeTitle(ENodeTitleType::FullTitle)); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "InvalidComponentTemplate_Error", "Invalid class '{TemplateClass}' used as template by '{NodeTitle}' for @@"), Args).ToString(), this); } if (UChildActorComponent const* ChildActorComponent = Cast<UChildActorComponent const>(Template)) { UBlueprint const* Blueprint = GetBlueprint(); UClass const* ChildActorClass = ChildActorComponent->GetChildActorClass(); if (ChildActorClass == Blueprint->GeneratedClass) { UEdGraph const* ParentGraph = GetGraph(); UEdGraphSchema_K2 const* K2Schema = GetDefault<UEdGraphSchema_K2>(); if (K2Schema->IsConstructionScript(ParentGraph)) { FFormatNamedArguments Args; Args.Add(TEXT("ChildActorClass"), FText::FromString(ChildActorClass->GetName())); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "AddSelfComponent_Error", "@@ cannot add a '{ChildActorClass}' component in the construction script (could cause infinite recursion)."), Args).ToString(), this); } } else if (ChildActorClass != nullptr) { AActor const* ChildActor = Cast<AActor>(ChildActorClass->ClassDefaultObject); check(ChildActor != nullptr); USceneComponent* RootComponent = ChildActor->GetRootComponent(); if ((RootComponent != nullptr) && (RootComponent->Mobility == EComponentMobility::Static) && (ChildActorComponent->Mobility != EComponentMobility::Static)) { FFormatNamedArguments Args; Args.Add(TEXT("ChildActorClass"), FText::FromString(ChildActorClass->GetName())); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "AddStaticChildActorComponent_Error", "@@ cannot add a '{ChildActorClass}' component as it has static mobility, and the ChildActorComponent does not."), Args).ToString(), this); } } } } else { FFormatNamedArguments Args; Args.Add(TEXT("NodeTitle"), GetNodeTitle(ENodeTitleType::FullTitle)); MessageLog.Error(*FText::Format(NSLOCTEXT("KismetCompiler", "MissingComponentTemplate_Error", "Unknown template referenced by '{NodeTitle}' for @@"), Args).ToString(), this); } }
PyObject *py_ue_get_owner(ue_PyUObject *self, PyObject * args) { ue_py_check(self); UActorComponent *component = ue_py_check_type<UActorComponent>(self); if (!component) return PyErr_Format(PyExc_Exception, "uobject is not a component"); Py_RETURN_UOBJECT(component->GetOwner()); }
UObject* ULevelSequence::GetParentObject(UObject* Object) const { UActorComponent* Component = Cast<UActorComponent>(Object); if (Component != nullptr) { return Component->GetOwner(); } return nullptr; }
PyObject *py_ue_destroy_component(ue_PyUObject * self, PyObject * args) { ue_py_check(self); UActorComponent *component = ue_py_check_type<UActorComponent>(self); if (!component) return PyErr_Format(PyExc_Exception, "uobject is not an UActorComponent"); component->DestroyComponent(); Py_RETURN_NONE; }
PyObject *py_ue_unregister_component(ue_PyUObject * self, PyObject * args) { ue_py_check(self); UActorComponent *component = ue_py_check_type<UActorComponent>(self); if (!component) return PyErr_Format(PyExc_Exception, "uobject is not an UActorComponent"); if (component->IsRegistered()) component->UnregisterComponent(); Py_RETURN_NONE; }
PyObject *py_ue_bind_key(ue_PyUObject *self, PyObject * args) { ue_py_check(self); char *key_name; int key; PyObject *py_callable; if (!PyArg_ParseTuple(args, "siO:bind_key", &key_name, &key, &py_callable)) { return NULL; } if (!PyCallable_Check(py_callable)) { return PyErr_Format(PyExc_Exception, "object is not a callable"); } UInputComponent *input = nullptr; if (self->ue_object->IsA<AActor>()) { input = ((AActor *)self->ue_object)->InputComponent; } else if (self->ue_object->IsA<UActorComponent>()) { UActorComponent *component = (UActorComponent *)self->ue_object; if (!component->GetOwner()) return PyErr_Format(PyExc_Exception, "component is still not mapped to an Actor"); input = component->GetOwner()->InputComponent; } else { return PyErr_Format(PyExc_Exception, "uobject is not an actor or a component"); } if (!input) { return PyErr_Format(PyExc_Exception, "no input manager for this uobject"); } UPythonDelegate *py_delegate = FUnrealEnginePythonHouseKeeper::Get()->NewDelegate(input, py_callable, nullptr); FInputKeyBinding input_key_binding(FKey(UTF8_TO_TCHAR(key_name)), (const EInputEvent)key); input_key_binding.KeyDelegate.BindDelegate(py_delegate, &UPythonDelegate::PyInputHandler); input->KeyBindings.Add(input_key_binding); Py_RETURN_NONE; }
PyObject *py_ue_register_component(ue_PyUObject *self, PyObject * args) { ue_py_check(self); if (!self->ue_object->IsA<UActorComponent>()) { return PyErr_Format(PyExc_Exception, "uobject is not a component"); } UActorComponent *component = (UActorComponent *)self->ue_object; component->RegisterComponent(); Py_INCREF(Py_None); return Py_None; }
//------------------------------------------------------------------------------ // Evolved from a combination of FK2ActionMenuBuilder::CreateAddComponentAction() // and FEdGraphSchemaAction_K2AddComponent::PerformAction(). UEdGraphNode* UBlueprintComponentNodeSpawner::Invoke(UEdGraph* ParentGraph, FBindingSet const& Bindings, FVector2D const Location) const { check(ComponentClass != nullptr); auto PostSpawnLambda = [](UEdGraphNode* NewNode, bool bIsTemplateNode, FCustomizeNodeDelegate UserDelegate) { UK2Node_AddComponent* AddCompNode = CastChecked<UK2Node_AddComponent>(NewNode); UBlueprint* Blueprint = AddCompNode->GetBlueprint(); UFunction* AddComponentFunc = FindFieldChecked<UFunction>(AActor::StaticClass(), UK2Node_AddComponent::GetAddComponentFunctionName()); AddCompNode->FunctionReference.SetFromField<UFunction>(AddComponentFunc, FBlueprintEditorUtils::IsActorBased(Blueprint)); UserDelegate.ExecuteIfBound(NewNode, bIsTemplateNode); }; FCustomizeNodeDelegate PostSpawnDelegate = FCustomizeNodeDelegate::CreateStatic(PostSpawnLambda, CustomizeNodeDelegate); // let SpawnNode() allocate default pins (so we can modify them) UK2Node_AddComponent* NewNode = Super::SpawnNode<UK2Node_AddComponent>(NodeClass, ParentGraph, FBindingSet(), Location, PostSpawnDelegate); // set the return type to be the type of the template UEdGraphPin* ReturnPin = NewNode->GetReturnValuePin(); if (ReturnPin != nullptr) { ReturnPin->PinType.PinSubCategoryObject = *ComponentClass; } bool const bIsTemplateNode = FBlueprintNodeTemplateCache::IsTemplateOuter(ParentGraph); if (!bIsTemplateNode) { UBlueprint* Blueprint = NewNode->GetBlueprint(); UActorComponent* ComponentTemplate = ConstructObject<UActorComponent>(ComponentClass, Blueprint->GeneratedClass); ComponentTemplate->SetFlags(RF_ArchetypeObject); Blueprint->ComponentTemplates.Add(ComponentTemplate); // set the name of the template as the default for the TemplateName param UEdGraphPin* TemplateNamePin = NewNode->GetTemplateNamePinChecked(); if (TemplateNamePin != nullptr) { TemplateNamePin->DefaultValue = ComponentTemplate->GetName(); } } // apply bindings, after we've setup the template pin ApplyBindings(NewNode, Bindings); return NewNode; }
void FSCSEditorViewportClient::DrawCanvas( FViewport& InViewport, FSceneView& View, FCanvas& Canvas ) { AActor* PreviewActor = GetPreviewActor(); if(PreviewActor) { if (GUnrealEd != NULL) { TArray<FSCSEditorTreeNodePtrType> SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes(); for (int32 SelectionIndex = 0; SelectionIndex < SelectedNodes.Num(); ++SelectionIndex) { FSCSEditorTreeNodePtrType SelectedNode = SelectedNodes[SelectionIndex]; UActorComponent* Comp = Cast<USceneComponent>(SelectedNode->FindComponentInstanceInActor(PreviewActor)); if (Comp != NULL && Comp->IsRegistered()) { // Try and find a visualizer TSharedPtr<FComponentVisualizer> Visualizer = GUnrealEd->FindComponentVisualizer(Comp->GetClass()); if (Visualizer.IsValid()) { Visualizer->DrawVisualizationHUD(Comp, &InViewport, &View, &Canvas); } } } } TGuardValue<bool> AutoRestore(GAllowActorScriptExecutionInEditor, true); const int32 HalfX = 0.5f * Viewport->GetSizeXY().X; const int32 HalfY = 0.5f * Viewport->GetSizeXY().Y; auto SelectedNodes = BlueprintEditorPtr.Pin()->GetSelectedSCSEditorTreeNodes(); if(bIsManipulating && SelectedNodes.Num() > 0) { USceneComponent* SceneComp = Cast<USceneComponent>(SelectedNodes[0]->FindComponentInstanceInActor(PreviewActor)); if(SceneComp) { const FVector WidgetLocation = GetWidgetLocation(); const FPlane Proj = View.Project(WidgetLocation); if(Proj.W > 0.0f) { const int32 XPos = HalfX + (HalfX * Proj.X); const int32 YPos = HalfY + (HalfY * (Proj.Y * -1)); DrawAngles(&Canvas, XPos, YPos, GetCurrentWidgetAxis(), GetWidgetMode(), GetWidgetCoordSystem().Rotator(), WidgetLocation); } } } } }
PyObject *py_ue_get_actor_label(ue_PyUObject *self, PyObject * args) { ue_py_check(self); if (self->ue_object->IsA<AActor>()) { AActor *actor = (AActor *)self->ue_object; return PyUnicode_FromString(TCHAR_TO_UTF8(*(actor->GetActorLabel()))); } if (self->ue_object->IsA<UActorComponent>()) { UActorComponent *component = (UActorComponent *)self->ue_object; return PyUnicode_FromString(TCHAR_TO_UTF8(*(component->GetOwner()->GetActorLabel()))); } return PyErr_Format(PyExc_Exception, "uobject is not an actor or a component"); }
void EmitProperties(FEmitterLocalContext& Context) { ensure(!NativeVariablePropertyName.IsEmpty()); if (bSetNativeCreationMethod) { Context.AddLine(FString::Printf(TEXT("%s->CreationMethod = EComponentCreationMethod::Native;"), *NativeVariablePropertyName)); } if (!ParentVariableName.IsEmpty()) { const FString SocketName = (AttachToName == NAME_None) ? FString() : FString::Printf(TEXT(", TEXT(\"%s\")"), *AttachToName.ToString()); Context.AddLine(FString::Printf(TEXT("%s->AttachTo(%s %s);"), *NativeVariablePropertyName, *ParentVariableName, *SocketName)); // AttachTo is called first in case some properties will be overridden. } UClass* ComponentClass = ComponentTemplate->GetClass(); for (auto Property : TFieldRange<const UProperty>(ComponentClass)) { FEmitDefaultValueHelper::OuterGenerate(Context, Property, NativeVariablePropertyName , reinterpret_cast<const uint8*>(ComponentTemplate) , reinterpret_cast<const uint8*>(ObjectToCompare) , FEmitDefaultValueHelper::EPropertyAccessOperator::Pointer); } }
PyObject *py_ue_get_owner(ue_PyUObject *self, PyObject * args) { ue_py_check(self); if (!self->ue_object->IsA<UActorComponent>()) { return PyErr_Format(PyExc_Exception, "uobject is not a component"); } UActorComponent *component = (UActorComponent *)self->ue_object; ue_PyUObject *ret = ue_get_python_wrapper(component->GetOwner()); if (!ret) return PyErr_Format(PyExc_Exception, "uobject is in invalid state"); Py_INCREF(ret); return (PyObject *)ret; }
void ULevelStreaming::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) { UProperty* OutermostProperty = PropertyChangedEvent.Property; if ( OutermostProperty != NULL ) { const FName PropertyName = OutermostProperty->GetFName(); if (PropertyName == GET_MEMBER_NAME_CHECKED(ULevelStreaming, LevelTransform)) { GetWorld()->UpdateLevelStreaming(); } if (PropertyName == GET_MEMBER_NAME_CHECKED(ULevelStreaming, EditorStreamingVolumes)) { RemoveStreamingVolumeDuplicates(); // Update levels references in each streaming volume for (TActorIterator<ALevelStreamingVolume> It(GetWorld()); It; ++It) { (*It)->UpdateStreamingLevelsRefs(); } } else if (PropertyName == GET_MEMBER_NAME_CHECKED(ULevelStreaming, LevelColor)) { // Make sure the level's Level Color change is applied immediately by reregistering the // components of the actor's in the level if( LoadedLevel != NULL ) { UPackage* Package = LoadedLevel->GetOutermost(); for( TObjectIterator<UActorComponent> It; It; ++It ) { if( It->IsIn( Package ) ) { UActorComponent* ActorComponent = Cast<UActorComponent>( *It ); if( ActorComponent ) { ActorComponent->RecreateRenderState_Concurrent(); } } } } } } Super::PostEditChangeProperty(PropertyChangedEvent); }
static UProperty *GetPropertyByName( UClass *InClass, const FName &Name ) { if ( InClass == NULL ) return NULL; UProperty *Property = GetPropertyByNameRecurse( InClass, Name.ToString() ); if ( Property != NULL ) { return Property; } AActor *AsActor = Cast<AActor>(InClass->ClassDefaultObject); if ( AsActor != NULL ) { FString ComponentPropertyName = Name.ToString(); int32 SplitIndex = 0; if ( ComponentPropertyName.FindChar( '.', SplitIndex ) ) { //FString ComponentName = ComponentPropertyName.LeftChop(SplitIndex); ComponentPropertyName = ComponentPropertyName.RightChop(SplitIndex+1); TInlineComponentArray<UActorComponent*> ActorComponents; AsActor->GetComponents(ActorComponents); for ( auto ComponentIt = ActorComponents.CreateIterator(); ComponentIt; ++ComponentIt ) { UActorComponent *Component = *ComponentIt; check( Component != NULL ); /* if ( Component->GetName() != ComponentName ) { continue; } */ Property = GetPropertyByNameRecurse( Component->GetClass(), ComponentPropertyName ); if ( Property != NULL ) { return Property; } } } } return NULL; }