I tried. It didn’t work. A new update to the code is that it saves the location of the BoxComponent. but it doesn’t appear in the Components window and I can’t interact with it by clicking it.
Can you please try, I would like to know if it is a problem with my local dev environment or with the code.
.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)
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();
#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
#include "BuildPreviewActor.h"
#include "UnrealEdGlobals.h"
#include "Editor/UnrealEdEngine.h"
#include "Engine/Engine.h" // Log ve gerekli fonksiyonlar için
#include "Kismet/GameplayStatics.h" // UGameplayStatics 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);
LoadChanges(); // 1. Actor oluşturulduğunda değişiklikleri yükle
}
void ABuildPreviewActor::OnConstruction(const FTransform& Transform)
{
Super::OnConstruction(Transform);
UE_LOG(LogTemp, Warning, TEXT("2. OnConstruction called"));
CreateBoxComponents(); // 3. OnConstruction'da çağrıldı
SaveChanges(); // 4. Değişiklikleri kaydet
}
void ABuildPreviewActor::PostLoad()
{
Super::PostLoad();
UE_LOG(LogTemp, Warning, TEXT("5. PostLoad called"));
LoadChanges(); // 6. PostLoad'da çağrıldı
}
void ABuildPreviewActor::PostInitializeComponents()
{
Super::PostInitializeComponents();
UE_LOG(LogTemp, Warning, TEXT("7. PostInitializeComponents called"));
CreateBoxComponents(); // 8. PostInitializeComponents'da çağrıldı
SaveChanges(); // 9. Değişiklikleri kaydet
}
void ABuildPreviewActor::PostInitProperties()
{
Super::PostInitProperties();
UE_LOG(LogTemp, Warning, TEXT("10. PostInitProperties called"));
CreateBoxComponents(); // 11. PostInitProperties'de çağrıldı
SaveChanges(); // 12. Değişiklikleri kaydet
}
void ABuildPreviewActor::PostActorCreated()
{
Super::PostActorCreated();
UE_LOG(LogTemp, Warning, TEXT("13. PostActorCreated called"));
CreateBoxComponents(); // 14. PostActorCreated'de çağrıldı
SaveChanges(); // 15. Değişiklikleri kaydet
}
void ABuildPreviewActor::BeginPlay()
{
Super::BeginPlay();
}
void ABuildPreviewActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
void ABuildPreviewActor::CreateBoxComponents()
{
UE_LOG(LogTemp, Warning, TEXT("16. CreateBoxComponents called"));
// Yeni veya var olan komponentleri kontrol et ve oluştur
for (FBoxComponentInfo& Info : BoxComponents)
{
if (!Info.BoxComponent)
{
UE_LOG(LogTemp, Warning, TEXT("17. Creating new BoxComponent"));
Info.BoxComponent = NewObject<UBoxComponent>(this, UBoxComponent::StaticClass(), NAME_None, RF_Transactional);
Info.BoxComponent->CreationMethod = EComponentCreationMethod::Instance;
Info.BoxComponent->SetHiddenInGame(false);
Info.BoxComponent->RegisterComponent();
}
else if (Info.BoxComponent->GetAttachParent() != RootComponent)
{
UE_LOG(LogTemp, Warning, TEXT("18. Attaching existing BoxComponent to RootComponent"));
Info.BoxComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
}
}
UpdateComponentRenderStates(); // 19. Bileşen render durumlarını güncelle
}
void ABuildPreviewActor::SaveChanges()
{
UE_LOG(LogTemp, Warning, TEXT("20. SaveChanges called"));
// Değişiklikleri kaydet
for (FBoxComponentInfo& Info : BoxComponents)
{
if (Info.BoxComponent)
{
Info.BoxComponent->Modify();
UE_LOG(LogTemp, Warning, TEXT("21. Modified BoxComponent"));
if (MarkPackageDirty())
{
UE_LOG(LogTemp, Warning, TEXT("22. Package marked dirty"));
}
else
{
UE_LOG(LogTemp, Warning, TEXT("23. Package not marked dirty"));
}
}
}
}
void ABuildPreviewActor::LoadChanges()
{
UE_LOG(LogTemp, Warning, TEXT("24. LoadChanges called"));
// Bileşenleri geri yükle
for (FBoxComponentInfo& Info : BoxComponents)
{
if (Info.BoxComponent && !Info.BoxComponent->IsRegistered())
{
Info.BoxComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepRelativeTransform);
Info.BoxComponent->RegisterComponent();
}
}
}
TArray<FBoxComponentInfo> ABuildPreviewActor::GetClothBoxes()
{
return BoxComponents;
}
void ABuildPreviewActor::UpdateComponentRenderStates()
{
UE_LOG(LogTemp, Warning, TEXT("25. 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("26. Marked render state dirty for BoxComponent"));
}
}
}
#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("27. PostEditChangeProperty: BoxComponents property changed"));
CreateBoxComponents(); // 28. BoxComponents değiştiğinde yeniden oluşturuluyor
SaveChanges(); // 29. Değişiklikleri kaydet
UpdateComponentRenderStates(); // 30. Bileşen render durumlarını güncelle
}
}
#endif