Fix (missing) timeline tracks + lost editable properties on 2nd scene load
FindActorById now skips stale TWeakObjectPtr entries instead of returning the first null match, RegisterActorId prunes stale + same-GUID entries before adding, and Clear() resets the ActorIds map so a fresh scenario starts with no ghost references. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -300,6 +300,10 @@ void UPS_Editor_TimelineSubsystem::Clear()
|
||||
bIsPlaying = false;
|
||||
LastAppliedValues.Empty();
|
||||
PrePlayBaseline.Reset();
|
||||
// Drop the old ActorIds — the previous scenario's actors have been destroyed and the
|
||||
// weak references are now stale. Keeping them around confuses FindActorById when the
|
||||
// next scenario happens to reuse the same FGuid (it can return a stale null entry).
|
||||
ActorIds.Reset();
|
||||
OnTimelineChanged.Broadcast();
|
||||
}
|
||||
|
||||
@@ -570,11 +574,18 @@ FGuid UPS_Editor_TimelineSubsystem::FindActorId(AActor* Actor) const
|
||||
AActor* UPS_Editor_TimelineSubsystem::FindActorById(const FGuid& Id) const
|
||||
{
|
||||
if (!Id.IsValid()) return nullptr;
|
||||
// Iterate every pair: the map can legitimately contain stale weak references from a
|
||||
// previous scenario whose actors were destroyed. Without this check the first match on
|
||||
// GUID can return a null key before we reach the live entry, giving "(missing)" after
|
||||
// the second load of the same scenario.
|
||||
for (const TPair<TWeakObjectPtr<AActor>, FGuid>& Pair : ActorIds)
|
||||
{
|
||||
if (Pair.Value == Id)
|
||||
{
|
||||
return Pair.Key.Get();
|
||||
if (AActor* Live = Pair.Key.Get())
|
||||
{
|
||||
return Live;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
@@ -583,6 +594,16 @@ AActor* UPS_Editor_TimelineSubsystem::FindActorById(const FGuid& Id) const
|
||||
void UPS_Editor_TimelineSubsystem::RegisterActorId(AActor* Actor, const FGuid& Id)
|
||||
{
|
||||
if (!Actor || !Id.IsValid()) return;
|
||||
// Prune any stale entries plus any previous entry holding the same GUID (the old actor
|
||||
// has been destroyed and replaced by this one). Keeps the map tight and ensures
|
||||
// FindActorById cannot hit a ghost key with the same GUID.
|
||||
for (auto It = ActorIds.CreateIterator(); It; ++It)
|
||||
{
|
||||
if (!It.Key().IsValid() || It.Value() == Id)
|
||||
{
|
||||
It.RemoveCurrent();
|
||||
}
|
||||
}
|
||||
ActorIds.Add(TWeakObjectPtr<AActor>(Actor), Id);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user