Hi - I’m trying to add a simple scene component (called HeldItemRoot) in C++ and attach it to my character mesh.
It looks fine in the editor when I compile and launch UE5 although the details panel is blank and it gets destroyed at launch when I hit play!?!?
I think I’m setting it up wrong? I’ve read others have had this issue historically but couldn’t find a good solution online. Any experts out there know the right way to get this working? Many thanks!
.h
public:
// Add Scene Component to hold item/weapon meshes
UPROPERTY(BlueprintReadWrite, VisibleAnywhere)
USceneComponent* HeldItemRoot;
.cpp
// Add Scene Component (Held Item Root) & attach to mesh
HeldItemRoot = CreateDefaultSubobject<USceneComponent>(TEXT("HeldItemRoot"));
HeldItemRoot->SetupAttachment(GetMesh());
You mean build a whole new blueprint child from scratch? My blueprint child of my c++ class has tons of code in it and I have other children of that. That would be a massive undertaking for something like this. Or do you mean something more simple?
This is how I would do it. Give it a shot. Code is untested:
auto newComponent = NewObject<USceneComponent>(this, USceneComponent::StaticClass());
if(newComponent)
{
HeldItemRoot = newComponent;
newComponent->AttachToComponent(GetMesh(), FAttachmentTransformRules::KeepRelativeTransform);
newComponent->RegisterComponent();
AddInstanceComponent(newComponent); // Refresh the editor so we can see the component
newComponent->Activate();
}
This should create a SceneComponent connected to the mesh returned by GetMesh.
NewObject with empty name can’t be used to create default subobjects (inside of UObject derived class constructor) as it produces inconsistent object names. Use ObjectInitializer.CreateDefaultSubobject<> instead.
Hi, yeah an absolutely confounding thing about the engine is you have to use a different call to add or attach a component in constructor vs. at runtime. Kinda ridiculous that they couldn’t just hide all that behind the scenes.
If you add a scene component in constructor it is like this:
BTW, you can make a nice, clean “AddComponent()” function by detecting the thread context and using the appropriate way to instantiate. Kinda annoying that we have to do this … but not aware there is another way?
Code for detecting thread context. There’s a function for both because sometime it reads better either way.
I didn’t realize where you were calling the code because you didn’t show that in your problem statement. My code should work when being called outside of the constructor. Shmoopy’s code should work inside of a constructor.
Thanks Both. My original code is in the constructor and looks like what @Shmoopy1701 is recommending though, right?
What’s the alternative to doing it out of the constructor? I could try the other way, but does that mean doing it in Begin Play? (Sorry, I’m newer to C++).
Actually, I’ve solved it by using my original code but reparenting my blueprint class to the Character class and then reparenting it back to my custom C++ class.
This seems like a bug for that to be the solution!?!?
Yes, it’s a known bug with the hot reload system. When changing something in a header file or constructor for an already blueprinted class, you should close the editor before compiling. Otherwise, you’ll need to do what you did and reparent your blueprint and then re-reparent it back.