Cannot See Array Of StaticMeshComponent

I have an actor that is supposed to hold an array of Static Mesh Components. I would like to assign these components in the subclass blueprints down the line. The problem is no matter what I use in the UPROPERTY it does not show up in the details panel of the project.

so far i have tried:
UPROPERTY(EditAnywhere, BlueprintReadWrite)
UPROPERTY(VisibleAnywhere, BlueprintReadWrite)

I always close the project and rebuild after any edit to try and make it show up.

Here is what I have in code at the moment


#pragma once

#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "PartInfo.h"
#include "Vis_Recce_Actor.generated.h"

UCLASS()
class MYPROJECT_API AVis_Recce_Actor : public AActor
{
	GENERATED_BODY()
	
public:	
	// Sets default values for this actor's properties
	AVis_Recce_Actor();

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<FPartInfo> partsAndInfoList;

	UPROPERTY(VisibleAnywhere, BlueprintReadWrite)
	TArray<UStaticMeshComponent*> partMeshes;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite, meta=(TitleProperty = "title"))
	TArray<FPartInfoLog> partLogs;

	UFUNCTION(BlueprintCallable)
	void SetPartHighlight(UStaticMeshComponent* smCo, bool isOn);
	
	UFUNCTION(BlueprintCallable)
	void SetPartPosHighlight(int pos, bool isOn);

	UFUNCTION()
	TArray<UStaticMeshComponent*> GetAllSMComps();

protected:
	// Called when the game starts or when spawned
	virtual void BeginPlay() override;

public:	
	// Called every frame
	virtual void Tick(float DeltaTime) override;

};

#pragma once

#include "CoreMinimal.h"
#include "UObject/NoExportTypes.h"
#include "PartInfo.generated.h"

/**
 * 
 */

USTRUCT(BlueprintType)
struct FPartInfoLog
{
	GENERATED_BODY() // Required macro

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString title;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<FString> info;
};

USTRUCT(BlueprintType)
struct FPartInfo
{
	GENERATED_BODY() // Required macro

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	UStaticMeshComponent* partStaticMesh;
	//TSoftObjectPtr<UStaticMesh> partSM;
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	TArray<FPartInfoLog> partInfo;
};


To further give context, I am making a system that will be able to highlight specific Static Mesh Components inside an actor blueprint. And once highlighted there is information that would be displayed along side it. Now each subclass of my actor will have their own different parts to highlight and each part will have its own different information.

Right now I am able to see the PartInfoLog perfectly fine. The string and array of string show without a hitch. The problem lies when I introduce the UStaticMeshComponent pointer to the equation. It will show the PartInfoLog but will not show anything to do with UStaticMeshComponent. I even tried to making two separated arrays, one for UStaticMeshComponent and one for PartInfoLog but It won’t show in the details panel.

Sorry i am past my morning coffee, so i did not look in your code, however last weekend i had similar problem with my code.

there are things i learned or discovered:

  • all components are initialized before actor, so any begin play or init in actor happens after init code in component. And this is really annoying since nothing short of tick and waiting that 0.2sec, or interface, and actor calling ActorIsReady() in component trough interface works.

  • First you have components init, then actor init, then begin play, then blueprints take over

  • and probably your case: when blueprint is loaded it WIPES all variables (and tags) from what was set in C++

ps.
now i try to read your post again, and make sense (for me) about you problem

Edit.
yes i think blueprint happily wipes C++ set variables.
I managed to slap that stupid blueprints with setting my variables in PostInit

my code to set components tags (after blueprints mercilessly wiped default stuff from C++):

void ACPP_CelestialBody::PostInitializeComponents()
{
	Super::PostInitializeComponents();
	
	if (RootGui)
	{
		// UE_LOG(LogTemp, Warning, TEXT("Post Init Root GUI"));
		RootGui->ComponentTags.AddUnique(FName(K2G_MANAGE_ROOT_WIDGET));
	}
	
	if (RootVisual)
	{
		// UE_LOG(LogTemp, Warning, TEXT("Post Init Root Visual"));
		RootVisual->ComponentTags.Add(FName(K2G_MANAGE_ROOT_MYMESH));	
	}
	
	if (BodyMesh)
	{
		// UE_LOG(LogTemp, Warning, TEXT("Post Init Body Mesh"));
		BodyMesh->ComponentTags.Add(FName(K2G_MANAGE_MYMESH));
		BodyMesh->ComponentTags.Add(FName(K2G_MANAGE_SCALE));
		BodyMesh->ComponentTags.Add(FName(K2G_MANAGE_MATERIAL));
	}
	NotifyComponentsOwnerIsReady();
}

and:
NotifyComponentsOwnerIsReady();

is that interface function i call to notify them that Really_Real_BeginGame happened, well from for loop inside it.

also my take on default arrays of stuff set in C++ (together with above wat to set defaults from C++ not from blueprints, where wiping or changing defaults happens after for eg. fixing blueprint compile errors from using live coding)

so my struct is like:

struct FPlanetData
{
	GENERATED_BODY()
	
	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString Name;  // Planet name

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	FString GamePlayTag;  // like sun.earth.moon

	UPROPERTY(EditAnywhere, BlueprintReadWrite)
	float BodyScale;

      // with much more data in struct.

then i make function that sets my array from const like this:

 bool UCPP_CommonFunctions::GetCelestialBodyData(const FGameplayTag& GameplayTag, FPlanetData& BodyData)
{
const TArray<FPlanetData> Bodies = {
    { "Sun", "sun.sun", 109.0f, 9, 0, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 609.12f, 7.25f },

then in void ACPP_CelestialBody::PostInitializeComponents() i set that array in spite of blueprints messing it all. And that GameplayTag is for actor to know which one entry it belongs to. And gameplay tag is only one variable i am setting per actor from blueprints.

ps.
i really hate that whole mess: components before actor, begin play almost never being begin play, then blueprints happily assuming what is default state, and happily reverting it to that (unless live coding fails and wipes it again to different state)

pps.
one more tip:

RootGui->ComponentTags.AddUnique(FName(K2G_MANAGE_ROOT_WIDGET));

K2G_MANAGE_ROOT_WIDGET - this is #DEFINE macro to always have same spelling for gameplay tag, limits headaches when seeking for misspelled names

Hello!

Yes actually you can’t do that in that way.
The component are not exposed because is an uobject for exposed a uobject to editor in that way needs to fulfil some conditions the static mesh component doesn’t

Or like @Nawrot mention about use a system of tags.

You can do this in other ways. Like doing a blueprint function and get all the static mesh you want as return value.

Not sure where to start.

I’m just going to try and type this through and feel free to correct me.

BTW thank you guys for being really fast I am taking time to respond because I’m researching and testing what you guys provide.

@JonathanBengoa
So what I’m getting at is that I can have an array of Static Mesh Components BUT since it is a UObject it needs to have specific conditions in order to be shown in the details panel. And because of this, when making an array of Static Mesh Components, the variable won’t show in the details panel because how Unreal handles the subclass generation for new actors. When the blueprint is loaded it hides the array of Static Mesh Components, that I want to add to, because it doesn’t have specific conditions.

Unfortunately I don’t want to make a blueprint function because I will be making like hundreds of these subclass blueprints (a bunch of different planes). It would be kind of a pain to have to make a blueprint for each individual subclass and re-edit all of them, if needed, in the future

@Nawrot
What would you suggest I do if I’m not settings this information in C++ but trying to set it in blueprints?

Right now I’m creating a parent class that would allow for easy creation of new assets down the line for designers and artists. That’s why I was trying to make a system that you can select individual parts of the actors for highlighting and also have their information attached as well for ease of use.

So my next question is, could I instead make the variable a static mesh, use
UPROPERTY(meta=(UseComponentPicker))
then cast it to a StaticMeshComponent when needing to access its SetRenderCustomDepth

If that wouldn’t work, what are the conditions needed for unreal to show what I need?

Communication/ variables from blueprints to C++ is usually messy, and together with live coding failing, which resets blueprint etc, it will be chaos in big project

For this i would suggest making blueprint with UMG tool, or even better c++ with slate tool. unreal tool actors/widgets can do much more with assets and actors in level.

yes picker could do, however with variables/references picked and set from blueprints it is very easy to crash project when blueprint randomly decides to wipe references.

ps.
during my recent battle with actors + components + blueprints wiping out default values. I keept asking chatGPT for my problems. While it usually gave bonker answers (for more complicated things) it gave me really good hints where to investigate next what is going on. So you could push your questions trough Yellow Rubber Duck (chat gpt). Just remember when you get out of its data set (comfort zone) it tends to make up answers to just please you. But even made up stuff sometimes has keywords that can be searched in googles for real information. And it nicely sumarries incoherrent rambling from when you try to find reason WHY EPIC?!

Thank you for your help! Time to look at the Slate. I will most likely come back and post my results for anyone in the future with the same problem.

Soe ideas/hints from what i have done with tools:

i created two blueprint+umg widget tools:

First is tool to create some planet systems. It uses L-System for making positions of planets. Then Data Assets to load look for planet. Then another Data Asset for planet description, and one more for planet ability list

all 3 data assets were created in blueprint widget editor tool, that had 2 of them in separate tabs. Then i could save each type of Data Asset, and then just set one data asset that keeps all: layout, visuals+description, and abilities as soft references do those data assets.

Data assets are easier to manage than data tables, or arrays of variables (together with tool using some naming policy for their folders and file names). I could (and i have) like 40 different data assets in folder that is not scanned by asset manager, then when i need some i just copy it to folder that is managed.

Second is tool that spits texture into separate RGBA and then rebuilds it back in order you pick. While it does not use data assets, it has one more script:

EVENT that can be run as tool. When i test one texture in widget side of tool, it creates and remember (in struct) what from RGBA goes where. When i am happy with version in widget, i can select multiple textures in content browser and run my EVENT/script on all of them.

ps.
first try data assets instead of array of structs, data assets at least survive blueprints mess.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.