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 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(); } } } }
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(); } } }
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; }
void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { for (FTaskArray::TIterator It(*Components); It; ++It) { UActorComponent* Component = *It; if (!Component->IsPendingKill() && Component->IsRegistered() && !Component->IsTemplate()) { FScopeCycleCounterUObject ComponentScope(Component); FScopeCycleCounterUObject AdditionalScope(STATS ? Component->AdditionalStatObject() : NULL); Component->DoDeferredRenderUpdates_Concurrent(); } } }
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_component_is_registered(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; if (component->IsRegistered()) { Py_INCREF(Py_True); return Py_True; } Py_INCREF(Py_False); return Py_False; }
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; if (!component->IsRegistered()) component->RegisterComponent(); Py_INCREF(Py_None); return Py_None; }
PyObject *py_ue_add_actor_component(ue_PyUObject * self, PyObject * args) { ue_py_check(self); PyObject *obj; char *name; PyObject *py_parent = nullptr; if (!PyArg_ParseTuple(args, "Os|O:add_actor_component", &obj, &name, &py_parent)) { return NULL; } if (!self->ue_object->IsA<AActor>()) { return PyErr_Format(PyExc_Exception, "uobject is not an AActor"); } AActor *actor = (AActor *)self->ue_object; if (!ue_is_pyuobject(obj)) { return PyErr_Format(PyExc_Exception, "argument is not a UObject"); } ue_PyUObject *py_obj = (ue_PyUObject *)obj; if (!py_obj->ue_object->IsA<UClass>()) { return PyErr_Format(PyExc_Exception, "argument is not a UClass"); } UClass *u_class = (UClass *)py_obj->ue_object; if (!u_class->IsChildOf<UActorComponent>()) { return PyErr_Format(PyExc_Exception, "argument is not a UClass derived from UActorComponent"); } USceneComponent *parent_component = nullptr; if (py_parent) { parent_component = ue_py_check_type<USceneComponent>(py_parent); if (!parent_component) { return PyErr_Format(PyExc_Exception, "argument is not a USceneComponent"); } } UActorComponent *component = NewObject<UActorComponent>(actor, u_class, FName(UTF8_TO_TCHAR(name)), RF_Public); if (!component) return PyErr_Format(PyExc_Exception, "unable to create component"); if (py_parent && component->IsA<USceneComponent>()) { USceneComponent *scene_component = (USceneComponent *)component; scene_component->SetupAttachment(parent_component); } if (actor->GetWorld() && !component->IsRegistered()) { component->RegisterComponent(); } if (component->bWantsInitializeComponent && !component->HasBeenInitialized() && component->IsRegistered()) component->InitializeComponent(); Py_RETURN_UOBJECT(component); }
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); } } } }
/** * Send all render updates to the rendering thread. */ void UWorld::SendAllEndOfFrameUpdates(FGraphEventArray* OutCompletion) { SCOPE_CYCLE_COUNTER(STAT_PostTickComponentUpdate); // update all dirty components. bPostTickComponentUpdate = true; if (!OutCompletion) { // this is a viewer or something, just do everything on the gamethread for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate); It; ++It) { ComponentsThatNeedEndOfFrameUpdate_OnGameThread.Add(*It); } ComponentsThatNeedEndOfFrameUpdate.Empty(ComponentsThatNeedEndOfFrameUpdate.Num()); } else { // remove any gamethread updates from the async update list for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate_OnGameThread); It; ++It) { ComponentsThatNeedEndOfFrameUpdate.Remove(*It); } } // Game thread updates need to happen before we go wide on the other threads. // These updates are things that have said that they are NOT SAFE to run concurrently. for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate_OnGameThread); It; ++It) { UActorComponent* Component = It->Get(); if (Component && !Component->IsPendingKill() && Component->IsRegistered() && !Component->IsTemplate()) { FScopeCycleCounterUObject ComponentScope(Component); FScopeCycleCounterUObject AdditionalScope(STATS ? Component->AdditionalStatObject() : NULL); Component->DoDeferredRenderUpdates_Concurrent(); } } if (ComponentsThatNeedEndOfFrameUpdate.Num()) { check(OutCompletion); enum { NUM_COMPONENTS_PER_TASK = 20 }; typedef TArray<UActorComponent*, TInlineAllocator<NUM_COMPONENTS_PER_TASK> > FTaskArray; /** Helper class define the task of calling DoDeferredRenderUpdates_Concurrent on an array of components **/ class FDoRenderthreadUpdatesTask { /** Array of components to process, owned by the task **/ TScopedPointer<FTaskArray> Components; public: FDoRenderthreadUpdatesTask(FTaskArray* InComponents) : Components(InComponents) { } FORCEINLINE TStatId GetStatId() const { RETURN_QUICK_DECLARE_CYCLE_STAT(DoRenderthreadUpdatesTask, STATGROUP_TaskGraphTasks); } static ENamedThreads::Type GetDesiredThread() { return ENamedThreads::AnyThread; } static ESubsequentsMode::Type GetSubsequentsMode() { return ESubsequentsMode::TrackSubsequents; } void DoTask(ENamedThreads::Type CurrentThread, const FGraphEventRef& MyCompletionGraphEvent) { for (FTaskArray::TIterator It(*Components); It; ++It) { UActorComponent* Component = *It; if (!Component->IsPendingKill() && Component->IsRegistered() && !Component->IsTemplate()) { FScopeCycleCounterUObject ComponentScope(Component); FScopeCycleCounterUObject AdditionalScope(STATS ? Component->AdditionalStatObject() : NULL); Component->DoDeferredRenderUpdates_Concurrent(); } } } }; { //@todo optimization, this loop could be done on another thread // First get the async transform and render data updates underway FTaskArray* Array = NULL; for (TSet<TWeakObjectPtr<UActorComponent> >::TIterator It(ComponentsThatNeedEndOfFrameUpdate); It; ++It) { UActorComponent* NextComponent = It->Get(); if (NextComponent && !NextComponent->IsPendingKill() && NextComponent->IsRegistered() && !NextComponent->IsTemplate()) { if (!Array) { Array = new FTaskArray; } Array->Add(NextComponent); if (Array->Num() == NUM_COMPONENTS_PER_TASK) { new (*OutCompletion) FGraphEventRef(TGraphTask<FDoRenderthreadUpdatesTask>::CreateTask(NULL, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(Array)); Array = NULL; // Array belongs to the task } } } if (Array) // partial array if we had one { new (*OutCompletion) FGraphEventRef(TGraphTask<FDoRenderthreadUpdatesTask>::CreateTask(NULL, ENamedThreads::GameThread).ConstructAndDispatchWhenReady(Array)); Array = NULL; // Array belongs to the task } } } bPostTickComponentUpdate = false; ComponentsThatNeedEndOfFrameUpdate.Empty(ComponentsThatNeedEndOfFrameUpdate.Num()); ComponentsThatNeedEndOfFrameUpdate_OnGameThread.Empty(ComponentsThatNeedEndOfFrameUpdate_OnGameThread.Num()); }