C++ Multiple Subcomponents in a component

I’m creating a custom ray visualizer right now that has two Points (SceneComponents) and draws a line between them. Both Points have yet another SceneComponent, a BillboardComponent, to visualize the points. However, the result in the editor is totally broken. I thought it might have to do with both BillboardComponents having the same name originally, hence I used the function “MakeUniqueObjectName”.

Currently my supposed hierarchy looks like this:

--- Actor: RayCollider
------ SceneComponent : RayComponent
----------- SceneComponent : PointA
----------------- SceneComponent : BillboardComponent
----------- SceneComponent : PointB
----------------- SceneComponent : BillboardComponent

With the following constructors:

ARayCollider:

ARayCollider::ARayCollider()
{ 
	rayComponent = CreateDefaultSubobject<URayComponent>("RayComponent");
	
	RootComponent = rayComponent;
}

URayComponent

URayComponent::URayComponent()
{
	bUseEditorCompositing = true;

	PointA = CreateDefaultSubobject<UPointComponent>("PointA");
	PointB = CreateDefaultSubobject<UPointComponent>("PointB");

	PointA->SetupAttachment(this);
	PointB->SetupAttachment(this);

}

UPointComponent:

UPointComponent::UPointComponent()
{

	billboardComp = CreateDefaultSubobject<UBillboardComponent>(MakeUniqueObjectName(this, UBillboardComponent::StaticClass(), "Sprite"));

	if (billboardComp)
	{
		// Structure to hold one-time initialization
		struct FConstructorStatics
		{
			ConstructorHelpers::FObjectFinderOptional<UTexture2D> TriggerTextureObject;
			FName ID_Triggers;
			FText NAME_Triggers;
			FConstructorStatics()
				: TriggerTextureObject(TEXT("/Engine/EditorResources/S_DecalActorIcon"))
				, ID_Triggers(TEXT("Triggers"))
				, NAME_Triggers(NSLOCTEXT("SpriteCategory", "Triggers", "Triggers"))
			{
			}
		};
		static FConstructorStatics ConstructorStatics;

		billboardComp->Sprite = ConstructorStatics.TriggerTextureObject.Get();
		billboardComp->RelativeScale3D = FVector(0.5f, 0.5f, 0.5f);
		billboardComp->bHiddenInGame = false;
		billboardComp->Sprite = ConstructorStatics.TriggerTextureObject.Get();
		billboardComp->SpriteInfo.Category = ConstructorStatics.ID_Triggers;
		billboardComp->SpriteInfo.DisplayName = ConstructorStatics.NAME_Triggers;
		billboardComp->bIsScreenSizeScaled = true;
	}

	billboardComp->SetupAttachment(this);
}

The resulting hierarchy is the following one:

PointA has its sprite/billboard comp correctly assigned under it, however, PointB does not. There are two sprites rendered, and the Sprite_0 one is the same one as when I edit the billboard component under “PointB” (exposed Billboard Component, hence I can edit the billboard Component that does not seem to exist under Point B in the shown hierarchy).
So the Sprite_0 that is parented to PointA is actually the component of PointB.

The other shown billboard component that is NOT shown in the hierarchy is available to edit under PointA’s exposed billboard component attributes. I fear that somehow subcomponents of components is not something UE4 correctly handles in C++…?

It looks like MakeUniqueObjectName is returning Sprite_0 for both the points (probably because you are passing “this” i.e., the point object as the parent so suffix 0 is unique to both of them)

Try creating your own unique names using a guid

FName SpriteName = *("Sprite_" + FGuid::NewGuid().ToString());
billboardComp = CreateDefaultSubobject<UBillboardComponent>(SpriteName);

Thanks, that did the trick. You never stop learning. Now I’m trying to figure out how to force a re-rendering of the FPrimitiveSceneProxy I’m using thise for…

I just tried it, thanks, it’s working,.:slight_smile:

Call MarkRenderStateDirty() from your component. This will recreate the proxy and you can push your new changes to it when it is recreated