I have recently moved from 4.3 to 4.4. In the past I have not ran into this specific error, although I do not know if it is only related to the move from 4.3 to 4.4.
While testing in PIE everything is operating as expected, but unfortunately after closing PIE an immediate error appears in the log, followed by an editor crash.
[2014.09.19-15.18.39:437][897]LogReferenceChain: (root) HS /Script/Hotsauce.Default__HSGameMode:HSSubobject->TestSector
[2014.09.19-15.18.39:438][897]LogReferenceChain: HSSector /Game/Maps/UEDPIE_0_Test01.Test01:PersistentLevel.HSBoard_1.HSSector_791->Property
[2014.09.19-15.18.39:438][897]LogReferenceChain: HSBoard /Game/Maps/UEDPIE_0_Test01.Test01:PersistentLevel.HSBoard_1->Property
[2014.09.19-15.18.39:439][897]LogReferenceChain: Level /Game/Maps/UEDPIE_0_Test01.Test01:PersistentLevel->OwningWorld
[2014.09.19-15.18.39:440][897]LogReferenceChain: (target) World /Game/Maps/UEDPIE_0_Test01.Test01
[2014.09.19-15.18.39:562][897]LogWindows:Error: appError called: Critical Error Package /Game/Maps/UEDPIE_0_Test01 Object from PIE level still referenced. Shortest path from root: (Object is not currently rooted)
It appears that the variable is not being released upon closing PIE. It has been declared using the UPROPERTY so GC should not have been an issue. I have also tried setting the variable manually to NULL/nullptr in the hopes that it would be cleared upon exiting, but that didn’t work ether.
I have found a workaround, but it doesn’t seem like it would be something that should be a long term solution. Also it should be noted that the scope of this problem only resides in the Game Mode class and have not tested elsewhere.
What does not work:
.h
UCLASS()
class SOME_API ASomeGameMode: public AGameMode
{
UPROPERTY()
TSubobjectPtr<USomeObject> SomeObjectVar;
UFUNCTION()
void SomeFunction(ASomeActorInLevel* AnActor);
}
.cpp
ASomeGameMode::ASomeGameMode(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP)
{
SomeObjectVar = PCIP.CreateDefaultSubobject<USomeObject>(this, TEXT("SomeObjectSubobject"));
}
void ASomeGameMode::SomeFunction(ASomeActorInLevel* AnActor) // same result for components
{
SomeObjectVar->TestVar = AnActor;
}
What dose work:
.h
UCLASS()
class SOME_API ASomeGameMode: public AGameMode
{
virtual void BeginPlay() override;
UPROPERTY()
USomeObject* SomeObjectVar;
UFUNCTION()
void SomeFunction(ASomeActorInLevel* AnActor);
}
.cpp
ASomeGameMode::ASomeGameMode(const class FPostConstructInitializeProperties& PCIP) : Super(PCIP) {}
void AHSGameMode::BeginPlay()
{
Super::BeginPlay();
SomeObjectVar = ConstructObject<USomeObject>(USomeObject::StaticClass(), this);
}
void ASomeGameMode::SomeFunction(ASomeActorInLevel* AnActor)
{
SomeObjectVar->SomeActorVar = AnActor;
}
This could probably all be avoided by creating static function with only temporary scoped variables but it would be nice to have modulated UObjects to encapsulated complex algorithms.
Thanks in advance.