[Bug] If I add a Static Mesh Comp in C++ and Attach to Mesh Socket in Constructor, No Comp In BP

Dear Friends at Epic,

In Beta4 and Beta5 I would do the following all the time

all in C++ constructor for a Character , which of course is instanced in-game using BP

  • get the static mesh asset via path
  • create the static mesh subobject
  • set the mesh
  • add this static mesh sub object to a Socket

final step

go into editor and compile the BP, even if it checkmarked as green, to cause a compile and make the component added in c++ appear.


Now in Beta6

I can do all but the step of adding to a socket

if I also add the native component to a socket in the C++ constructor

then when I go into the Editor, the component does not appear even after clicking the compile button!

I’ve tested this numerous times.

#General Comment

Adding Components via C++ has never worked properly for me, starting with Beta4, they never appear in game until I go into the Editor and recompile the blueprint, and the blueprint does not indicate it knows it is missing a component, but the editor does crash if I do not write out the .cpp part, so it does know it is there.

But I have to click the already-green compile button to get the comp to appear.

this was true in Beta4 and Beta5

But now in Beta6

#UE4 is losing support for adding Static Mesh Components via C++

I consider this a severe bug

because I add components via C++ for a reason

Via c++ I am adding and removing armor and weapons from character mesh sockets, weapons that are part of the Character

It is the most efficient way to set up such an weapon/armor inventory

rather than making instanced actors for each weapon and attaching actor to actor (ridiculously less efficient and much more confusing)

I need to be able to add static mesh components via C++ for UE4 to be functioning for my game’s needs.

#My Previous Thread on This Issue

Have to click already-green checkmark for adding new Native Components
https://rocket.unrealengine.com/questions/6839/staticmeshcomponent-added-in-c-only-shows-after-cl.html

this is true for static mesh as well as skeletal mesh components

#Repro

create a static mesh sub object in c++ for a Character similar to this:

#.h

This is an ACharacter Class

//ArmoredView
	TSubobjectPtr ArmoredJoyfulView;
	UStaticMesh* AssetSM_ArmoredView;
FORCEINLINE void SetupSMComponentsWithCollision(UStaticMeshComponent* Comp)
	{
		if(!Comp) return;
		//~~~~~~~~
		
		Comp->bOwnerNoSee = false;
		Comp->bCastDynamicShadow = true;
		Comp->CastShadow = true;
		Comp->BodyInstance.SetObjectType(ECC_WorldDynamic);
		Comp->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
		Comp->SetHiddenInGame(false);
	}

#.cpp
//Constructor

//Asset, FROM CODE (cannot use BP since BP properties not valid till after constructor)
static ConstructorHelpers::FObjectFinder StaticMeshOb_AW(TEXT("StaticMesh'/Game/VictoryGoals/Mechs/Windturtle/Upper/WindTurtleArmoredView.WindTurtleArmoredView'"));

AssetSM_ArmoredView = StaticMeshOb_AW.Object;
	
//Create and Add
ArmoredJoyfulView = PCIP.CreateDefaultSubobject < UStaticMeshComponent > (this, TEXT("Happy1"));
Components.Add(ArmoredJoyfulView);
	
//Set Mesh
ArmoredJoyfulView->SetStaticMesh(AssetSM_ArmoredView);
	
//Setup (see .h)
SetupSMComponentsWithCollision(ArmoredJoyfulView);
	
//Attach to socket
//ArmoredJoyfulView->AttachTo(Mesh, FName(TEXT("ArmoredView"))); 

//If I uncomment this, the component disappears from the Editor BP of this Character, 
//and I have to change the name of the subobject to get it to appear again.

Then you can go into the editor and try to add the component.

It should appear,

but then go back and uncomment the line with the adding to socket,

and recompile the C++

and then recompile the BP in the Editor

at this point the component disappears, for me, in Beta6.

#Is the Asset Being Found?

Yes, please, I checked that

#Please Help

I am seeing support for native static mesh components deterioriating, not improving

Rama

#My Overall Tone

Please note at all times I am after what is best for UE4 engine and the ultimate success of Epic, I am just being loud in this thread to get attention to an issue that I was told would be addressed back in Oct `13


#Update & Workaround

If I move the part of attaching the newly created subobject out of the constructor, into post init,

then everything is fine, and indeed everything works in game too

//NOT in constructor, under any circumstances,
//removes the component from the BP!
//Attach to socket
ArmoredJoyfulView->AttachTo(Mesh, FName(TEXT("ArmoredView"))); 

I did not have to do this in beta5 or beta4, I could keep this in the c++ constructor


#Native Support for Components Needs to be Addressed


This has been going on in my observations since I posted this thread

https://rocket.unrealengine.com/questions/6839/staticmeshcomponent-added-in-c-only-shows-after-cl.html

#That Was October `13

Can whoever is responsible for this aspect of the engine please take a deep look at this

#Rama Relax

The reason I am so intent about this is because I already reported this as an issue, and now it is getting worse, not better.

Hopefully you can appreciate why that is making me try to be “louder” to get attention to this issue.

This time I found a workaround, but what about next time, if this is not addressed properly?

PS:

If this is somehow limited to my project or my build, then I withdraw any extra emotions about it,
but this native component adding weirdness is still affecting me and has now taken up several hours of my productivity

#Insight

Could this issue be because the Mesh who has the socket I am trying to attach to is not yet set in the constructor?

I’ve noticed most BP properties are not valid until after c++ post init, and the Mesh for a Character would be included in that I suppose.

But then why did my exact same method work in Beta4 and Beta5, without any issues other than the already-green recompile of the Character BP ?

Please let me know what your repro uncovers, I think this issue is worth a c++ repro attempt

Hey Rama -

As you surmised, you cannot do attachment in the constructor, and the reason is that you can’t be sure that all the properties are valid until after the properties have initialized.

The construction path goes something like this:

  • Run up the native constructors
  • Let native children override the components of their parents, if necessary
  • Serialize the CDO properties, if this is ultimately a blueprint class

Until all that is completed, you cannot be sure that the components are all ready for you to manipulate by attaching other components.

We used to have the NativeConstructionScript for places like this, which would allow you a handy hook to do attachment after you knew the native components were ready. However, we got rid of this in the hopes that people would use the component’s AttachParent and AttachSocketName, which handles the deferred attachment, and is what you can safely use in the constructor. Instead of:

ArmoredJoyfulView->AttachTo(Mesh, FName(TEXT("ArmoredView"))); 

Try using:

ArmoredJoyfulView.AttachParent = Mesh;
ArmoredJoyfulView.AttachSocketName = FName(TEXT("ArmoredView")
);

Hope that helps, and sorry for the pain!

"We used to have the NativeConstructionScript for places like this, which would allow you a handy hook to do attachment after you knew the native components were ready. However, we got rid of this in the hopes that people would use the component’s AttachParent and AttachSocketName, which handles the deferred attachment, and is what you can safely use in the constructor.

Instead of:

ArmoredJoyfulView->AttachTo(Mesh, FName(TEXT("ArmoredView"))); 

Try using:

ArmoredJoyfulView.AttachParent = Mesh;
ArmoredJoyfulView.AttachSocketName = FName(TEXT("ArmoredView")
);"

The above is awesome, and is the info I needed,

Thank you Nick!

I just needed to know the deferred work flow

#You’re Awesome Nick!

Rama

PS: if you convert your response into an answer I can mark this thread as resolved :slight_smile:

#Complete C++ Code Sample For You

For anyone researching this issue, here is a complete code sample that works,

thanks to Nick’s information about using deferred attachment I can now entirely setup a new Actor Static Mesh Component via the C++ constructor

#.h

//JoyControl
	TSubobjectPtr JoyfulControl;
	UStaticMesh * AssetSM_JoyControl;
	
FORCEINLINE void SetupSMComponentsWithCollision(UStaticMeshComponent* Comp)
	{
		if(!Comp) return;
		//~~~~~~~~
		
		Comp->bOwnerNoSee = false;
		Comp->bCastDynamicShadow = true;
		Comp->CastShadow = true;
		Comp->BodyInstance.SetObjectType(ECC_WorldDynamic);
		Comp->BodyInstance.SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
		Comp->BodyInstance.SetResponseToAllChannels(ECR_Ignore);
		Comp->BodyInstance.SetResponseToChannel(ECC_WorldStatic, ECR_Block);
		Comp->BodyInstance.SetResponseToChannel(ECC_WorldDynamic, ECR_Block);
		Comp->BodyInstance.SetResponseToChannel(ECC_Pawn, ECR_Block);
		Comp->SetHiddenInGame(false);
	}

:slight_smile:

#.Cpp Constructor

//Asset, Reference Obtained Via Right Click in Editor
static ConstructorHelpers::FObjectFinder StaticMeshOb_AW2(TEXT("StaticMesh'/Game/VictoryGoals/Mechs/JoyControl/JoyControl_WindTurtle.JoyControl_WindTurtle'"));

AssetSM_JoyControl = StaticMeshOb_AW2.Object;

//Create and Add
JoyfulControl = PCIP.CreateDefaultSubobject < UStaticMeshComponent > (this, TEXT("JoyfulControlYay"));
Components.Add(JoyfulControl);

//Set Mesh
JoyfulControl->SetStaticMesh(AssetSM_JoyControl);

//Setup (see .h)
SetupSMComponentsWithCollision(JoyfulControl);

//Deferred Attachment (Ty Nick W.! Actual attach gets done after blueprint stuff)
JoyfulControl->AttachParent = Mesh;
JoyfulControl->AttachSocketName = FName(TEXT("JoyControl"));

#Picture of Result in Editor

I cannot use your way of deferred attachment like:

because it’s a private member.
Is it a change made with Unreal 5 or is it something obvious i miss?

Thanks for this detailed issue anyway. It’s the only one I could find adressing this problem.