I have a struct that retains data on every room in the game, including the occupants of said room. I’m trying to use a TMap as an ad-hoc map of the world, and among other things I want to iterate through a room’s occupants and spawn them (if the level is loading) or despawn them (if it’s unloading). The following looks right to be, but it crashes every time DepopulateRoom() is called:
USTRUCT()
struct FRoomData{
GENERATED_USTRUCT_BODY()
UPROPERTY(BlueprintReadOnly)
FString name;
UPROPERTY(BlueprintReadOnly)
int32 ID;
UPROPERTY(BlueprintReadOnly)
TArray<AMCharacter*> occupants;
TMap<float, FCharacterSheet> SpawnRules; //characters FCharacterSheet who must spawn at float time
bool operator == (const FRoomData& src) const{
return (ID == src.ID);
}
};
TMap<ARoom*, FRoomData> CharacterLocations; //TMap retaining references to data struct for each room in the game, organized by room
void UPopulationManager::DepopulateRoom(ARoom* room){
for (int i = 0; i < CharacterLocations.FindOrAdd(room).occupants.Num(); i++){ //Iterate through every actor in ARoom*, shift it from active pool to inactive pool, and delete it
MakeInactive(CharacterLocations[room].occupants[i]->characterData->characterSheet);
CharacterLocations[room].occupants[i]->Destroy(); //Despawn actor
}
}
I’m not sure what I’ve done wrong here; I start iterating through CharacterLocations with TMap.FindOrAdd(key), so I know I’m not trying to access a key that doesn’t exist in the map, but I know the problem is something in DepopulateRoom.
Edited to add: here’s the crashlog, sorry for not including it originally.
Unknown exception - code 00000001 (first/second chance not available)
"Fatal error: [File:D:\BuildFa
UE4Editor_Core!FDebug::AssertFailed() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\core\private\misc\outputdevice.cpp:354]
UE4Editor_CoreUObject!FGCCollector::HandleObjectReference() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\coreuobject\private\uobject\garbagecollection.cpp:409]
UE4Editor_CoreUObject!FSimpleObjectReferenceCollectorArchive::operator<<() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\coreuobject\public\uobject\garbagecollection.h:462]
UE4Editor_CoreUObject!UObjectProperty::SerializeItem() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\coreuobject\private\uobject\propertyobject.cpp:32]
UE4Editor_CoreUObject!UMapProperty::SerializeItem() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\coreuobject\private\uobject\propertymap.cpp:394]
UE4Editor_CoreUObject!FArchiveRealtimeGC::ProcessObjectArray() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\coreuobject\private\uobject\garbagecollection.cpp:868]
UE4Editor_CoreUObject!TGraphTask::ExecuteTask() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\core\public\async\taskgraphinterfaces.h:797]
UE4Editor_Core!FTaskThread::ProcessTasks() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\core\private\async\taskgraph.cpp:539]
UE4Editor_Core!FTaskThread::ProcessTasksUntilQuit() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\core\private\async\taskgraph.cpp:340]
UE4Editor_Core!FTaskThread::Run() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\core\private\async\taskgraph.cpp:690]
UE4Editor_Core!FRunnableThreadWin::Run() [d:\buildfarm\buildmachine_++depot+ue4-releases+4.9\engine\source\runtime\core\private\windows\windowsrunnablethread.cpp:74]
The specific error quoted in the text log was:
Fatal error: [File:D:\BuildFarm\buildmachine_++depot+UE4-Releases+4.9\Engine\Source\Runtime\CoreUObject\Private\UObject\GarbageCollection.cpp] [Line: 412]
Invalid object in GC: 0x00000096adb28100, ReferencingObject: PopulationManager /Temp/Autosaves/Game/TemporaryAssets/UEDPCPrototypeLevel.PrototypeLevel:PersistentLevel.WorldManager_C_0.Population Manager, ReferencingProperty: NULL
Since it’s GC, I assume it’s directly linked to my Destroy() call, but taking a second look at the code I quoted above I’m not sure where it would be calling Destroy() on a null pointer.