I have a SpawnVolume class that inherits from AActor. On its header I have:
public:
UPROPERTY(VisibleInstanceOnly, Category = Spawning)
class UBoxComponent* WhereToSpawn;
And on constructor I have:
ASpawnVolume::ASpawnVolume(const FObjectInitializer& ObjectInitializer) : Super(ObjectInitializer)
{
// Set this character to call Tick() every frame. You can turn this off to improve performance if you don't need it.
PrimaryActorTick.bCanEverTick = true;
WhereToSpawn = ObjectInitializer.CreateDefaultSubobject<UBoxComponent>(this, TEXT("WhereToSpawn"));
RootComponent = WhereToSpawn;
This code works fine. But if I use USceneComponent instead of UBoxComponent, WhereToSpawn is NULL. It is not NULL only on constructor.
If I continue using USceneComponent and I remove UPROPERTY declaration it works (WhereToSpawn is not NULL).
Maybe your actor is pending to kill? It can happen when you create “impossible” objects.
I sure had such problem, but don’t remember if it was the case. Anyway try to debug step this code and see what happen. Check object flags.
Or maybe your uproperty flags are not correct.
I’ve ran into issues with changing a subobject’s type and then loading the project. An easy workaround is to change the subobject’s name, so when loading existing instances or blueprints of your actor class the editor doesn’t try to load any saved data for that subobject:
Edit: The reason the loading runs into issues is because when the editor tries to load a saved instance of your SpawnVolume (like one placed in your map or a blueprint asset that inherits from SpawnVolume), it sees saved data for a subobject called “WhereToSpawn” but the saved type (UBoxComponent) doesn’t match the run-time type (USceneComponent). Ideally, the editor would map the saved data as best as it could- in this case, recognize that UBoxComponent is a subclass of USceneComponent and load all variables they have in common. I don’t know whether the editor actually attempts this but I’ve encountered many times where this doesn’t succeed, so usually I just use the above workaround to make the asset load again without errors.
Why it have error “WhereToSpawn” ?? at FVector SpawnOrigin=WhereToSpawn->Bounds.Origin; and FVector SpawnExtend = WhereToSpawn->Bounds.BoxExtent;
#include "BatteryCollector.h"
#include "SpawnVolume.h"
#include "Kismet/KismetMathLibrary.h"
#include "Pickup.h"
// Sets default values
ASpawnVolume::ASpawnVolume()
{
// 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;
//Create the Box Compoonent to represent the spawn volume
WhereToSpawn = CreateDefaultSubobject<UBoxComponent>(TEXT("WhereToSpawn"));
RootComponent = (USceneComponent*)WhereToSpawn;
}
// Called when the game starts or when spawned
void ASpawnVolume::BeginPlay()
{
Super::BeginPlay();
}
// Called every frame
void ASpawnVolume::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
}
FVector ASpawnVolume::GetRandomPointInVolume()
{
FVector SpawnOrigin = WhereToSpawn->Bounds.Origin;
FVector SpawnExtend = WhereToSpawn->Bounds.BoxExtent;
return UKismetMathLibrary::RandomPointInBoundingBox(SpawnOrigin, SpawnExtend);
}
NEVER use C-Style casts like this - that’s the first thing. You don’t even need the cast, you can just set it directly. (I really hope the official tutorials don’t teach this.)
Make sure you have included the header for BoxComponent: