Creating multiple components in constructor

I’m trying to create multiple Static Meshes in the constructor and since I don’t want to create 10 UStaticMeshComponents manually, I need a method to create them in a for loop. I found AddComponent, but I don’t know what the last parameter should look like.

for (int32 i = 0; i < 5; i++)
{
	FString j = "Mesh" + i;
	AddComponent(FName(*j), false, FTransform(FVector( 0.f, 0.f, 0.f)), UStaticMeshComponent);
}

The method needs an UObject pointer. Am I using the wrong method?

What has previously worked for me is using CreateDefaultSubobject This way you’d get the following:

RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("OBJRoot"));
for (int32 i = 0; i < 5; i++)
 {
     FString j = "Mesh" + i;
     CreateDefaultSubobject<UstaticMeshComponent>(FName(*j));
 }

Hope this works for you too!

The above code actually failed when packaging to Android, so I had to replace it with:

 RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("OBJRoot"));
 for (int32 i = 0; i < 5; i++)
  {
      FString j = TEXT("Mesh");
      FString iString = FString::FromInt( i );
      j.Append( iString );
      CreateDefaultSubobject<UstaticMeshComponent>(FName(*j));
  }

Also the documentation explicitly tells you should always use the TEXT macro.
link text

from my latest project, hope it helps for future readings

	for (int32 i = 0; i < MESH_NUMBER; i++){
		MeshArray.Add(CreateDefaultSubobject<UStaticMeshComponent>(*FString("Mesh"+FString::FromInt(i))));
		MeshArray[i]->SetStaticMesh(mesh_finder.Object); //if construction helper exists
		MeshArray[i]->SetupAttachment(DummyScene);
	}

Would totally add MeshArray.Reserve since it’s in the constructor and the number of elements is known. Also it makes more sense to save it as FName, since it won’t be renamed and it doesn’t need the functions of FString. But you are right, the SetStaticMesh and SetupAttachement functions were missing in my answer. <3

About saving the references to a Static Mesh Array. I would still use Reserve ;P. Also, it depends if you want to save the Static Meshes in an array. In my example I don’t have to access/ change the meshes, I just needed a visual representation and if the class gets destroyed, the components will be destroyed as well. So, if you need to access the Static Meshes, sure, you can save the reference to an array.

More interesting is the FName stuff. This line compiled in my project:

CreateDefaultSubobject<UStaticMeshComponent>(FName(*j));

I created an FName with a pointer to a string. The string was dynamic? (I assume that means that you can change it) anyway, so I don’t understand your objection. However, I need to check if this line still compiles in newer versions and if it crashes.

no, MeshArray exists so you could have array of pointers to component. With previous examples none of pointers to components is stored. My example adds components plus you will have all components’ pointers stored in array so you could access it with:

MeshArray[index]->DoSomething();

f.e. change relative location of 5th component:

MeshArray[5]->SetRelativeLocation(FVector(0,50,50));

MeshArray is defined as array of UStaticMeshComponents:

TArray <class UStaticMeshComponent*> MeshArray;

As for FName, it cannot have one FName, cause UE4 crashes, components must have unique name, that’s why you have to make it dynamic depending of i

so in my example:

*FString("Mesh"+FString::FromInt(i)

is actually FName, cause:

FName Name = *Fstring String;

you can define FName before, but it must be dynamic!

Cheers!

I understand, you don’t need pointer reference to the components.

As for objection, it was not objection but reply to your “Also it makes more sense to save it as FName, since it won’t be renamed and it doesn’t need the functions of FString” cause on contrary, it makes sense not to declare any of FStrings like you did before creating subobjects. In my example CreateDefaultSubobject gets FName directly without making temporary unnecessary strings (BTW I also assumed you said it like it can be just one FName, my wrong, by dynamic I meant it can be dynamically changed by the code in this case depending of index number. Your examples are dynamic).

Cheers!

Pardon my confusing phrasing, I indeed created an FString with FString::FromInt( i ) and saved it temporary, but does it make a difference? Also from the docs, I learned to always use the TEXT macro instead of a “naked” string like you do with “Mesh”. Would be great to hear your thoughts on that.