I have a ALevelSequenceActor* SequenceActor that was created when I called the ULevelSequencePlayer::CreateLevelSequencePlayer function in a subsystem method I wrote. When my sequence finished playing the SequenceActor was still visible in the World Outliner in the unreal editor. Replaying the sequence created another SequenceActor so the World Outliner was being flooded with ALevelSequenceActor. I decided to figure out how to safely delete objects in the world through the code, and I found this thread from 2014 that had a custom written function in it that would allow the deletion of UObjects because no other way existed in the engine.
Well it’s been 8 years since that post. Has the engine had functionality added to it since then to delete objects and actors, or is this thread still the best way to do that? Ideally I’m looking for a single function call to delete an actor and remove it from the World Outliner.
Here is my code for reference:
.h header file
//The array of LevelSequences to be played.
TArray<ULevelSequence*> CameraRoute;
//These pointers play the level sequences in CameraRoute.
ULevelSequencePlayer* SequencePlayer;
ALevelSequenceActor* SequenceActor; //<- I have to delete this actor manually or he floods the editor when I play many ULevelSequences.
//Called when a sequence is finished to start the next sequence.
FScriptDelegate SequenceFinishedDelegate;
.cpp file
bool RunRoute()
{
if (CameraRoute.Num())
{
UWorld* CurrentWorld = GetWorld();
if (CurrentWorld != nullptr)
{
FMovieSceneSequencePlaybackSettings PlaybackSettings;
SequencePlayer = ULevelSequencePlayer::CreateLevelSequencePlayer(CurrentWorld->PersistentLevel, CameraRoute[iCurrentSequence], PlaybackSettings, SequenceActor);
if (SequencePlayer != nullptr)
{
SequencePlayer->OnFinished.Add(SequenceFinishedDelegate);
SequencePlayer->Play();
return true;
}
}
}
return false;
}
void OnSequenceFinished()
{
iCurrentSequence++;
if (iCurrentSequence < CameraRoute.Num())
{
//There are more sequences to play, destroy the SequenceActor from the previous sequence before starting a new one. Otherwise the SequenceActor will remain in the World Outliner.
VDestroy(SequenceActor);
RunRoute();
}
else
{
//Sequences finished playing.
iCurrentSequence = 0;
//Destroy the last SequenceActor.
VDestroy(SequenceActor);
}
}
void VDestroy(UObject* ToDestroy)
{
if (!ToDestroy) return;
if (!ToDestroy->IsValidLowLevel()) return;
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//Actor?
AActor * AnActor = Cast(ToDestroy);
if (AnActor)
{
AnActor->K2_DestroyActor();
ToDestroy = NULL;
}
//Object - BeginDestroy
else
{
//Begin Destroy
ToDestroy->ConditionalBeginDestroy();
ToDestroy = NULL;
}
//GC
GetWorld()->ForceGarbageCollection(true);
}