I am trying to get the default subobjects (in this case static mesh components) for a blueprint class which derived from a native class.
The problem is the default object only contains the components defined in the native class.
I can’t get the components which were defined later in the child blueprint class.
All of this is for an inventory system, that displays items by retrieving the mesh components from the class and constructing a new actor for this specific purpose.
this is the function that sets up the actor for the inventory:
void AInventoryMesh::SetupInventoryMesh(TSubclassOf<class AItem> BaseClass, UClass* SubClass, USceneComponent* TargetRoot)
//if we have a subclass, let it represent the item and ignore the baseclass
//that is because there are items like the "constructionkit" which contains
//a specific building piece for example a fence or stairs.
//and to know which part is inside this construction kit we use the subclass instead
UClass* chosenClass = SubClass ? SubClass : BaseClass;
//get the default object
//?? this seems to only contain the native defined components
//and not the ones defined in the deriving blueprint
AActor* defaultObj = chosenClass->GetDefaultObject<AActor>();
//we remember the first used component
UStaticMeshComponent* newParentMesh = nullptr;
UStaticMeshComponent* templateParentMesh = nullptr;
TArray<UActorComponent*> subComps = defaultObj->GetComponentsByClass(UStaticMeshComponent::StaticClass());
for (auto comp : subComps)
UStaticMeshComponent* meshComp = Cast<UStaticMeshComponent>(comp);
//create and register a cloned mesh component
UStaticMeshComponent* meshClone = ConstructObject<UStaticMeshComponent>(UStaticMeshComponent::StaticClass(), this);
//copy the properties
for (int i = 0; i < meshComp->GetNumMaterials(); i++)
//if we already had a first component...
//...attach all following components to this first component
//and use the offset from the first default component to the current default component
//as the new relative position
meshClone->SetRelativeLocationAndRotation(meshComp->GetComponentLocation() - templateParentMesh->GetComponentLocation(), meshComp->GetComponentRotation());
//...else we attach it to the rootcomponent
//and remember the current components
newParentMesh = meshClone;
templateParentMesh = meshComp;
meshClone->AttachTo(RootComponent, NAME_None, EAttachLocation::SnapToTarget);
//then we attach this new actor, which represents an item inside of the inventory
//to a previous defined uscenecomponent which is positioned at the slot this item
AttachRootComponentTo(TargetRoot, NAME_None, EAttachLocation::SnapToTarget);
//then scale the actor to fit inside the visual slot of the inventory GUI
FVector scale = FVector(UHelperFunctions::GetActorScaleToFitInRadius(this, 6.f));
//move the actor so that it is centered in the slot
FVector offset = UHelperFunctions::GetActorLocalOffsetToCenter(this);
Now I have a base class “AStructure” which defines the basic building parts.
It contains only 1 mesh component by default - and this is the one that I can get from the default object.
I have a structure “stairs” which consists of the basic mesh and 2 additional mesh components for the railings.
These 2 components were added afterwards in the derived blueprint from “AStructure”, but I can’t get those “extra” components to build up my inventory actor.
Maybe there is another way to get the missing components?
This just hit me, too. I need to pull data off of an object before I spawn it in order to be able to spawn it. That data is missing for blueprint classes since all of their components disappear. Not sure how I’m going to work around this one…
Same issue. I’m at a loss for why this is happening… I can get the CDO for the blueprint class, and it has all of the correct values that were set in the blueprint class defaults… however any blueprint created components are mysteriously absent. Even more odd is that they will occasionally appear as valid pointers, but they will be pointing to garbage memory.
UBlueprints and blueprint nodes are editor only objects. Any build that does not include editor code (Shipping will not) will have no concept of these, which will cause a compile error when you attempt to build in that configuration. Blueprint generated classes can be used, however. (i.e MyBlueprint_C"), as these exist outside of the editor framework.
I see parts of UBlueprint have #if WITH_EDITOR, but not the entire object. It also doesn’t override IsEditorOnly (which by default returns false). The SimpleConstructionScript (which contains the nodes) isn’t wrapped with any #ifs, so appears to be valid in non-editor builds. The fact that you can spawn blueprint classes in shipping builds means the components/properties stored in the UBlueprint have to be available somewhere. It seems like either UBlueprint has to work in shipping builds, or the components and properties get moved out to another class in non-editor builds?
Since a few people were doubtful about my previous answer working in shipped builds, the following is code we use in our game, unmodified, that definitely works in a Shipping build. The gist of it is: Blueprints have two lists for components we care about: UInheritableComponentHandler and USimpleConstructionScript.
The USimpleConstructionScript contains templates for components declared in the current blueprint, possibly overriding a native component.
Whereas the UInheritableComponentHandler contains templates overriding a component declared in a parent blueprint (always seems to point to a node in a USimpleConstructionScript). Hence the ordering of which component template to choose as the desired candidate in the following function.
There is another AnswerHub post with a similar answer here: