The way I add Components to Actor via Editor Utility Widget

If you want to add Components to your Actor in EUW, your scripts will be something like this.

In my situation, this will not work as it is expected.
I added Box Component, and it appears in Scene, but not in details panel.
And, If I move the Actor, the box will disapper.

There is a reason for this, but it’s tricky.
If You copy the actor and paste it into text editor, You can get something like this.

Begin Map
   Begin Level
      Begin Actor Class=/Script/Engine.Actor Name=Actor_0 Archetype=/Script/Engine.Actor'/Script/Engine.Default__Actor'
         Begin Object Class=/Script/Engine.SceneComponent Name="DefaultSceneRoot"
         End Object
         Begin Object Class=/Script/Engine.BoxComponent Name="BoxComponent_0"
         End Object
         Begin Object Name="DefaultSceneRoot"
            bVisualizeComponent=True
            CreationMethod=Instance
         End Object
         Begin Object Name="BoxComponent_0"
            AreaClass=Class'"/Script/NavigationSystem.NavArea_Obstacle"'
            AttachParent=SceneComponent'"DefaultSceneRoot"'
            CreationMethod=UserConstructionScript
         End Object
         RootComponent=SceneComponent'"DefaultSceneRoot"'
         ActorLabel="Actor"
         InstanceComponents(0)=SceneComponent'"DefaultSceneRoot"'
      End Actor
   End Level
Begin Surface
End Surface
End Map

BoxComponent has a property called “CreationMethod”. By default,the value will be “userConstructionScript”, when the component was made via blueprints.

That is causing a problem.

If I change the value to “Instance” in text editor, and paste back to UE, the components will show up correctly.

So, I have to change “CreationMethod” from “UserConstructionScript” to “Instance”, when I add component in Blueprint.

The way I found is creat a cutsom blueprint node by using c++.

C++ offers a functionaily to do that. Here is a sample of my custom blueprint.

Custom_BP_LibraryBPLibrary.cpp

#include "Custom_BP_LibraryBPLibrary.h"
#include "Custom_BP_Library.h"

#include "ComponentInstanceDataCache.h"


UActorComponent* UCustom_BP_LibraryBPLibrary::SetCreationMethod(UActorComponent* ActorComponent, EComponentCreationMethod method)
{
	if (ActorComponent != nullptr) {
		ActorComponent->CreationMethod = method;
	}
	return ActorComponent;
}

Custom_BP_LibraryBPLibrary.h

#pragma once

#include "Kismet/BlueprintFunctionLibrary.h"
#include "Custom_BP_LibraryBPLibrary.generated.h"


UCLASS()
class UCustom_BP_LibraryBPLibrary : public UBlueprintFunctionLibrary
{
	GENERATED_UCLASS_BODY()

		UFUNCTION(BlueprintCallable, Category = "Custom_BP_LibraryTesting")
		static UActorComponent* SetCreationMethod(UActorComponent* ActorComponent, EComponentCreationMethod method);


};

If I put this node after adding component, now I can add any components to Actor by using this Editor Utility Widget.

But there is another small problem left.

If I add component to my Actor, sometimes the component will not show up in details panel.
Refreshing details panel by selecting other Actor makes it show up.
So the script is surely working, but something is going wrong.

I encounterd very complicated process through fixing those issues, and something remain unsolved.
I think there must be things that need to be fixed.
what do you think?

Any help would be greatly appreciated.

1 Like

Hello!
I’ve used your method to add a component from a editor utility widget and it works perfectly !
However, I want to remove the component but i’ve only found the “DestroyComponent” node but it doesn’t seem to work.
Do you have any idea on how can i remove my component ?

I’d like to add after having problems with the asset not saving that you need to also “Transact” the object so the engine knows it has been edited. Otherwise once the component gets added, save everything and open the level again the actor will have reverted back to how it was before the component was added.

3 Likes

Great ! I’ve been struggling with this problem for a while. thanks a lot!

Great job haruhito_o!
After adding component, Details window will not update. But you can use UpdateEditorWindow function/node.

UFUNCTION(BlueprintCallable)
static void UpdateEditorWindow(AActor* TargetActor)
{
// Deselect the actor
GEditor->SelectActor(TargetActor, false, true);

	// Reselect the actor
	GEditor->SelectActor(TargetActor, true, true);

	// Notify the editor that the selection changed (this can force a details panel refresh)
	GEditor->NoteSelectionChange();
	
}

but remember to add include “Editor.h”
and update your Build.cs file with “UnrealEd”
PublicDependencyModuleNames.AddRange(new string { Your modules, “UnrealEd” });

There is one issue left.
After creating(adding) component , and deleting, and creating once again…Unreal will crush.
But if we create, delete, save and reload scene, than add again…UE will not crush.

Hi.

So the superior way to do this is to simply call

YourActor->AddInstanceComponent(YourComponent);

That automatically changes the CreationMethod to “Instance”. It also makes it so the changes save properly to your actor blueprint.

So you can use features such as “Apply Instance Changes to Blueprint”, and the new component will actually save back to the original actor blueprint.

You can use it like this:


UPhysicsConstraintComponent* PhysicsConstraintComponent = NewObject<UPhysicsConstraintComponent>(DestructibleStructureActor);
	
DestructibleStructureActor->AddInstanceComponent(PhysicsConstraintComponent);

PhysicsConstraintComponent->RegisterComponent();

PhysicsConstraintComponent->AttachToComponent(DestructibleStructureActor->GetRootComponent(), FAttachmentTransformRules::KeepWorldTransform);
2 Likes