Hello, I’m trying to refresh an actor when I change a property in the engine.
The actor owns a property (“Spawning Rooms”) telling how many rooms it should spawn.
Through PostEditChangeProperty I can refresh the actor, regenerating the rooms.
To do so, I call a DestroyComponent() to the pointer to the previously saved SceneComponents, and then regenerate the whole dungeon.
Doing so, the rooms initially created (and only them) disappear forever, while the rooms generated later appear and disappear correctly.
I have a main actor “Floor” and a SceneComponent “Room”.
Floor.h
#include "GameFramework/Actor.h"
#include "YARGRoom.h"
#include "YARGFloor.generated.h"
UCLASS()
class YARGPROTO_API AYARGFloor : public AActor
{
GENERATED_BODY()
public:
AYARGFloor(const class FObjectInitializer& ObjectInitializer);
virtual void BeginPlay() override;
virtual void Tick( float DeltaSeconds ) override;
virtual void PostEditChangeProperty(struct FPropertyChangedEvent& PropertyChangedEvent) override;
virtual void GenerateFloor();
virtual void CleanAndGenerate();
protected:
TArray<UYARGRoom*> RoomsArray;
UPROPERTY(EditAnywhere, Category="Floor Options")
uint32 TileSize;
UPROPERTY(EditAnywhere, Category = "Floor Options")
uint32 WorldSize;
UPROPERTY(EditAnywhere, Category = "Floor Options")
uint32 MinRoomSide;
UPROPERTY(EditAnywhere, Category = "Floor Options")
uint32 MaxRoomSide;
UPROPERTY(EditAnywhere, Category = "Floor Options")
uint32 SpawningRooms;
UPROPERTY(EditAnywhere, Category = "Floor Options")
uint32 SpawningEllipseWidth;
UPROPERTY(EditAnywhere, Category = "Floor Options")
uint32 SpawningEllipseHeight;
private:
};
Floor.cpp
#include "YARGProto.h"
#include "YARGFloor.h"
#include "YARGMath.h"
AYARGFloor::AYARGFloor(const class FObjectInitializer& ObjectInitializer)
: Super(ObjectInitializer)
, TileSize(100)
, WorldSize(10000)
, MinRoomSide(2)
, MaxRoomSide(5)
, SpawningRooms(5)
, SpawningEllipseWidth(5000)
, SpawningEllipseHeight(5000)
{
GenerateFloor();
PrimaryActorTick.bCanEverTick = true;
}
// Called when the game starts or when spawned
void AYARGFloor::BeginPlay()
{
Super::BeginPlay();
}
void AYARGFloor::Tick( float DeltaTime )
{
Super::Tick( DeltaTime );
}
void AYARGFloor::PostEditChangeProperty(FPropertyChangedEvent & PropertyChangedEvent)
{
CleanAndGenerate();
Super::PostEditChangeProperty(PropertyChangedEvent);
}
void AYARGFloor::CleanAndGenerate()
{
for (UYARGRoom* pRoom : RoomsArray)
{
pRoom->DestroyComponent();
}
RoomsArray.Empty();
GenerateFloor();
}
void AYARGFloor::GenerateFloor()
{
RoomsArray.Init(SpawningRooms);
for (uint32 uiRoomIndex = 0; uiRoomIndex < SpawningRooms; ++uiRoomIndex)
{
UYARGRoom* NewRoom = NewObject<UYARGRoom>(this, *FString::Printf(TEXT("Room %u"), uiRoomIndex));
RoomsArray[uiRoomIndex] = NewRoom;
NewRoom->AttachTo(RootComponent);
}
}
The SceneComponent Room has nothing specific.
Initial situation:
I correctly see all the 5 default rooms.
From there, if I set more than 5 rooms:
while if I set less than 5 rooms:
Note: if I set 6 , 8 and again 6, i see 1, 3 and 1 rooms, so it doesn’t seems a name conflict.
Any help is appreciated, thanks in advance.