C++ Actors in Level are broken, but newly added ones work fine

Hi there!
I have the following problem: I have Cover actors with an editor function to recreate some information they hold (their type of cover).
Now when I run this function (GenerateCoverTypeWrapper()), I receive a nullptr for my root component (CoverComponent), which holds all the actual cover information and functions.
Now when I create a new Cover actor, and hit the function, everything is fine!
This leads me to the assumption that both actors (old and fresh one) are different, and that the old actors are broken because they were differently constructed then the new ones.
I even tried to fire the RerunConstructionScripts() function in the editor, without success. Here the c++ files:

Cover.h

// Copyright by Felix Voigt

#pragma once

#include "CoreMinimal.h"
#include "AI/EQS/CoverComponent.h"
#include "Components/ArrowComponent.h"
#include "Components/BillboardComponent.h"
#include "Components/BoxComponent.h"
#include "Data/MoveTargetContainer.h"
#include "GameFramework/Actor.h"
#include "Cover.generated.h"

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

	//Displays the disclosed Cover Type of the Cover Component
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = Cover)
	ECoverType CoverTypeDisplay;

	//Displays the disclosed Cover Peek Direction of the Cover Component
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, meta=(Bitmask, BitmaskEnum=CoverPeekDirectionMask), Category = Cover)
	uint8 CoverPeekDirectionDisplay;
	
	UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category = Cover)
	UCoverComponent* CoverComponent;
	
#if WITH_EDITOR

private:
	//UPROPERTY(BlueprintReadOnly, VisibleAnywhere, Category=Cover)
	UPROPERTY()
	UBillboardComponent* BillboardComponent;

	UPROPERTY()
	class UTexture2D* HighCoverTexture;

	UPROPERTY()
	class UTexture2D* LowCoverTexture;

	UPROPERTY()
	class UTexture2D* NoCoverTexture;
	
	UPROPERTY()
	UArrowComponent* CoverDirectionComponent;

	UPROPERTY()
	UBoxComponent* CoverBoxComponent;

#endif

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

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

	virtual void PostEditMove(bool bFinished) override;

	virtual void PostEditUndo() override;

#if WITH_EDITOR
	
	UFUNCTION(BlueprintCallable, CallInEditor, DisplayName = GenerateCoverType,  Category = Cover)
	void GenerateCoverTypeWrapper();

	UFUNCTION(BlueprintCallable, CallInEditor, DisplayName = GenerateCoverTypesForAll,  Category = Cover)
	void GenerateCoverTypesForAllWrapper() const;

	UFUNCTION(BlueprintCallable, CallInEditor, DisplayName = GenerateCoverTypesForAll,  Category = Cover)
	void ReConstruct();

#endif

};

Cover.cpp

// Copyright by Felix Voigt


#include "AI/EQS/Cover.h"
#include "Kismet/GameplayStatics.h"

// Sets default values
ACover::ACover()
{
 	// Set this actor to call Tick() every frame.  You can turn this off to improve performance if you don't need it.
	PrimaryActorTick.bCanEverTick = false;

	CoverComponent = CreateDefaultSubobject<UCoverComponent>(TEXT("Cover Point Component"));
	if(CoverComponent)
	{
		CoverComponent->Mobility = EComponentMobility::Static;
		SetRootComponent(CoverComponent);
		//UE_LOG(LogTemp, Warning, TEXT("ComponentSet"));
	}

#if WITH_EDITOR

	ConstructorHelpers::FObjectFinderOptional<UTexture2D> FullShieldTextureObject(TEXT("Texture2D'/Game/HarrisonProject/UI/Textures/Icons/T_IconShieldInverted_Full.T_IconShieldInverted_Full'"));
	ConstructorHelpers::FObjectFinderOptional<UTexture2D> HalfShieldTextureObject(TEXT("Texture2D'/Game/HarrisonProject/UI/Textures/Icons/T_IconShieldInverted_Half.T_IconShieldInverted_Half'"));
	ConstructorHelpers::FObjectFinderOptional<UTexture2D> NoShieldTextureObject(TEXT("Texture2D'/Game/HarrisonProject/UI/Textures/Icons/T_IconRedCross.T_IconRedCross'"));

	HighCoverTexture = FullShieldTextureObject.Get();
	LowCoverTexture = HalfShieldTextureObject.Get();
	NoCoverTexture = NoShieldTextureObject.Get();
	
	BillboardComponent = CreateEditorOnlyDefaultSubobject<UBillboardComponent>(TEXT("Cover Icon"));
	if(BillboardComponent)
	{
		BillboardComponent->bIsScreenSizeScaled = true;
		BillboardComponent->ScreenSize = 0.0005f;
		BillboardComponent->Sprite = NoCoverTexture;
		BillboardComponent->SetupAttachment(RootComponent);
		BillboardComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
		BillboardComponent->SetRelativeLocation(FVector(0.0f,0.0f, 25.0f));
	}

	CoverDirectionComponent = CreateEditorOnlyDefaultSubobject<UArrowComponent>(TEXT("Cover Direction Arrow"));
	if(CoverDirectionComponent)
	{
		CoverDirectionComponent->SetupAttachment(RootComponent);
		CoverDirectionComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
		CoverDirectionComponent->SetRelativeLocation(FVector(0.0f,0.0f, 50.0f));
		CoverDirectionComponent->SetRelativeRotation(GetActorForwardVector().ToOrientationRotator());
		CoverDirectionComponent->ArrowSize = 0.5f;
	}

	CoverBoxComponent = CreateEditorOnlyDefaultSubobject<UBoxComponent>(TEXT("Cover Box Component"));
	if(CoverBoxComponent)
	{
		CoverDirectionComponent->SetupAttachment(RootComponent);
		CoverBoxComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::SnapToTargetNotIncludingScale);
		CoverBoxComponent->SetBoxExtent(FVector(30.0f, 30.0f, 100.0f));
		CoverBoxComponent->SetRelativeLocation(FVector(0.0f,0.0f, 100.0f));
	}

	GenerateCoverTypeWrapper();
	
#endif
}

// Called when the game starts or when spawned
void ACover::BeginPlay()
{
	Super::BeginPlay();	
}

// Called every frame
void ACover::Tick(float DeltaTime)
{
	Super::Tick(DeltaTime);
}

void ACover::PostEditMove(bool bFinished)
{
	Super::PostEditMove(bFinished);
	GenerateCoverTypeWrapper();
}

void ACover::PostEditUndo()
{
	Super::PostEditUndo();
	GenerateCoverTypeWrapper();
}


#if WITH_EDITOR
void ACover::GenerateCoverTypeWrapper()
{	
	CoverComponent->GenerateCoverType();

	CoverTypeDisplay = CoverComponent->GetCoverType();
	CoverPeekDirectionDisplay = CoverComponent->GetCoverPeekDirection();

	switch (CoverTypeDisplay)
	{
		case ECoverType::CT_HighCover :
			UE_LOG(LogTemp, Warning, TEXT("High"));
			BillboardComponent->Sprite = HighCoverTexture;
			CoverBoxComponent->SetBoxExtent(FVector(30.0f, 30.0f, 100.0f));
			CoverBoxComponent->SetRelativeLocation(FVector(0.0f,0.0f, 100.0f));
			break;
		
		case ECoverType::CT_LowCover :		
			UE_LOG(LogTemp, Warning, TEXT("Low"));
			BillboardComponent->Sprite = LowCoverTexture;			
			CoverBoxComponent->SetBoxExtent(FVector(30.0f, 30.0f, 50.0f));
			CoverBoxComponent->SetRelativeLocation(FVector(0.0f,0.0f, 50.0f));
			break;
		
		case ECoverType::CT_NoCover :
			UE_LOG(LogTemp, Warning, TEXT("No"));
			BillboardComponent->Sprite = NoCoverTexture;		
			CoverBoxComponent->SetBoxExtent(FVector(30.0f, 30.0f, 0.0f));
			CoverBoxComponent->SetRelativeLocation(FVector(0.0f,0.0f, 0.0f));
			break;
	}


}

void ACover::GenerateCoverTypesForAllWrapper() const
{
	TArray<AActor*> AllCoverItems;
	UGameplayStatics::GetAllActorsOfClass(this, ACover::StaticClass(), AllCoverItems);

	for (AActor* CoverActorIterator : AllCoverItems)
	{
		Cast<ACover>(CoverActorIterator)->GenerateCoverTypeWrapper();
	}
}

void ACover::ReConstruct()
{
	RerunConstructionScripts();
}
#endif

Thank you in advance for your time!

I’ve been making some research and have found this reddit discussion:

The problem seems to be the same as described over there: probably I’ve edited the constructor and saved the level with non default values for the objects (as the one variable being a nullptr), which are being serialized and causing my problem.

But the the thread delivers no answer: is there an easy way to reinitialize the actors with their default constructors?

Based on your comment, if you don’t want variable to be serialized use Transient specifier on UPROPERTY, variables without UPROPERTY also would not save as engine wont have idea of there existence, just don’t use UObject pointers on those as it may generated invalid pointer on that variable

Mh, well it’s not like I don’t want it serialized at all, as they hold the cover information that is important to the game and should only be generated in the editor.
Nevertheless, I’ve set the Properties to Transient, rebuilt, reopened the map. removed the Transient, built again and saved the map.
Now the faulty nullptr Component was recreated and saved, problem solved. Thank you!