While in the editor, I add an element to the array created by C++ and connect the added element to RootComponent. Everything works fine, but when I close and reopen the engine, size of elements of the array is same, but I cannot see that element in Components window, it disappears. I am not sure if the problem is not being saved or loaded.
.h
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "Components/BoxComponent.h"
#include "SimulatorGame/SimulatorGameGameMode.h"
#include "BuildPreviewActor.generated.h"
USTRUCT(BlueprintType)
struct FBoxComponentInfo
{
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Instanced, Category = "Components")
UBoxComponent* BoxComponent;
FBoxComponentInfo()
: BoxComponent(nullptr)
{}
};
UCLASS()
class SIMULATORGAME_API ABuildPreviewActor : public AActor
{
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ABuildPreviewActor();
UPROPERTY(EditDefaultsOnly)
UStaticMeshComponent* MeshAsset;
UPROPERTY(EditDefaultsOnly)
UMaterial* MeshMaterial;
UPROPERTY(EditDefaultsOnly)
UMaterial* PreviewCanBuildMaterial;
UPROPERTY(EditDefaultsOnly)
UMaterial* PreviewNotCanBuildMaterial;
UPROPERTY()
ASimulatorGameGameMode* SimulatorGameGameMode;
UFUNCTION()
TArray<FBoxComponentInfo> GetClothBoxes();
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Components")
TArray<FBoxComponentInfo> BoxComponents;
virtual void OnConstruction(const FTransform& Transform) override;
virtual void PostLoad() override;
virtual void PostInitializeComponents() override;
virtual void PostInitProperties() override;
virtual void PostActorCreated() override;
void CreateBoxComponents();
void SaveChanges();
void LoadChanges();
void UpdateComponentRenderStates(); // Yeni fonksiyon
#if WITH_EDITOR
virtual void PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
UPROPERTY()
TArray<UBoxComponent*> ClothBoxes;
public:
// Called every frame
virtual void Tick(float DeltaTime) override;
};
.cpp
.cpp
#include "BuildPreviewActor.h"
#include "Engine/Engine.h" // Log ve gerekli fonksiyonlar için
// Sets default values
ABuildPreviewActor::ABuildPreviewActor()
{
// Set this actor to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
MeshAsset = CreateDefaultSubobject<UStaticMeshComponent>("MeshAsset");
SetRootComponent(MeshAsset);
}
void ABuildPreviewActor::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
UE_LOG(LogTemp, Warning, TEXT("OnConstruction called"));
CreateBoxComponents(); // OnConstruction'da çağrıldı
}
void ABuildPreviewActor::PostLoad()
{
Super::PostLoad();
UE_LOG(LogTemp, Warning, TEXT("PostLoad called"));
CreateBoxComponents(); // PostLoad'da çağrıldı
}
void ABuildPreviewActor::PostInitializeComponents()
{
Super::PostInitializeComponents();
UE_LOG(LogTemp, Warning, TEXT("PostInitializeComponents called"));
CreateBoxComponents(); // PostInitializeComponents'da çağrıldı
}
void ABuildPreviewActor::PostInitProperties()
{
Super::PostInitProperties();
UE_LOG(LogTemp, Warning, TEXT("PostInitProperties called"));
CreateBoxComponents(); // PostInitProperties'de çağrıldı
}
void ABuildPreviewActor::PostActorCreated()
{
Super::PostActorCreated();
UE_LOG(LogTemp, Warning, TEXT("PostActorCreated called"));
CreateBoxComponents(); // PostActorCreated'de çağrıldı
}
void ABuildPreviewActor::CreateBoxComponents()
{
UE_LOG(LogTemp, Warning, TEXT("CreateBoxComponents called"));
// Yeni veya var olan komponentleri kontrol et ve oluştur
for (FBoxComponentInfo& Info : BoxComponents)
{
if (!Info.BoxComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Creating new BoxComponent"));
Info.BoxComponent = NewObject<UBoxComponent>(this, UBoxComponent::StaticClass(), NAME_None, RF_Transactional);
Info.BoxComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
Info.BoxComponent->CreationMethod = EComponentCreationMethod::Instance;
Info.BoxComponent->RegisterComponent();
}
else if (Info.BoxComponent->GetAttachParent() != RootComponent)
{
UE_LOG(LogTemp, Warning, TEXT("Attaching existing BoxComponent to RootComponent"));
Info.BoxComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
}
}
SaveChanges(); // Değişiklikleri kaydet
UpdateComponentRenderStates(); // Bileşen render durumlarını güncelle
}
#if WITH_EDITOR
void ABuildPreviewActor::PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent)
{
Super::PostEditChangeProperty(PropertyChangedEvent);
FName PropertyName = (PropertyChangedEvent.Property != nullptr) ? PropertyChangedEvent.Property->GetFName() : NAME_None;
if (PropertyName == GET_MEMBER_NAME_CHECKED(ABuildPreviewActor, BoxComponents))
{
UE_LOG(LogTemp, Warning, TEXT("PostEditChangeProperty: BoxComponents property changed"));
CreateBoxComponents(); // BoxComponents değiştiğinde yeniden oluşturuluyor
SaveChanges(); // Değişiklikleri kaydet
UpdateComponentRenderStates(); // Bileşen render durumlarını güncelle
}
}
#endif
void ABuildPreviewActor::SaveChanges()
{
UE_LOG(LogTemp, Warning, TEXT("SaveChanges called"));
// Değişiklikleri kaydet
for (FBoxComponentInfo& Info : BoxComponents)
{
if (Info.BoxComponent)
{
Info.BoxComponent->Modify();
UE_LOG(LogTemp, Warning, TEXT("Modified BoxComponent"));
}
}
if (MarkPackageDirty())
{
UE_LOG(LogTemp, Warning, TEXT("Package marked dirty"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("Package not marked dirty"));
}
}
void ABuildPreviewActor::LoadChanges()
{
UE_LOG(LogTemp, Warning, TEXT("LoadChanges called"));
// Yükleme işlemi
// Burada gerekli yükleme işlemleri yapılabilir, örneğin bir SaveGame/LoadGame mekanizması kullanılabilir.
}
TArray<FBoxComponentInfo> ABuildPreviewActor::GetClothBoxes()
{
return BoxComponents;
}
void ABuildPreviewActor::UpdateComponentRenderStates()
{
UE_LOG(LogTemp, Warning, TEXT("UpdateComponentRenderStates called"));
// Tüm bileşenlerin render durumlarını güncelle
for (FBoxComponentInfo& Info : BoxComponents)
{
if (Info.BoxComponent)
{
Info.BoxComponent->MarkRenderStateDirty();
UE_LOG(LogTemp, Warning, TEXT("Marked render state dirty for BoxComponent"));
}
}
}
For looking to the problem;
[video] When editing the array
[video] After close and reopening the engine


