Description

When a Level Sequence’s Camera Cut track with When Finished = Keep State is played, the “original state” is persisted into the PreAnimatedStorage array inside FPreAnimatedCameraCutStorage. From the next playback onward, the backup destination changes to the TransientPreAnimatedStorage array. (See TPreAnimatedStateStorage::AssignPreAnimatedValue())

void AssignPreAnimatedValue(FPreAnimatedStorageIndex StorageIndex, EPreAnimatedStorageRequirement StorageRequirement, StorageType&& InNewValue)
{
	check(StorageIndex);

	FCachedData& CachedData = PreAnimatedStorage[StorageIndex.Value];

	if (StorageRequirement == EPreAnimatedStorageRequirement::Persistent)
	{
		ensure(!CachedData.bInitialized);
		CachedData.Value = MoveTemp(InNewValue);
		CachedData.bPersistent = true;
		CachedData.bInitialized = true;
	}
	else if (StorageRequirement == EPreAnimatedStorageRequirement::Transient)
	{
		ensure(!CachedData.bInitialized || !TransientPreAnimatedStorage.Contains(StorageIndex));

		// Assign the transient value
		if (!CachedData.bInitialized)
		{
			CachedData.Value = MoveTemp(InNewValue);
			CachedData.bInitialized = true;
		}
		else
		{
			TransientPreAnimatedStorage.Add(StorageIndex, MoveTemp(InNewValue));
		}
	}
}

However, during restore, the code path attempts to fetch cached values only from PreAnimatedStorage via TPreAnimatedCameraCutStorage::GetCachedValue().

const StorageType& GetCachedValue(FPreAnimatedStorageIndex StorageIndex) const
{
	static const StorageType DefaultValue = StorageType();

	if (ensure(PreAnimatedStorage.IsValidIndex(StorageIndex.Value)))
	{
		const FCachedData& CachedData = PreAnimatedStorage[StorageIndex.Value];
		if (CachedData.bInitialized)
		{
			return CachedData.Value;
		}
	}
	return DefaultValue;
}

As a result, the backup and the restore operation no longer match: the state that was backed up into the transient storage is not the one being restored from the persistent storage.

This becomes especially visible when a player respawn is involved (as in the repro steps), because the restore path can no longer access a valid camera object, making the incorrect cached view-target resolution more apparent.

Note:

To reproduce this bug, at least one Level Sequence Actor must exist in the scene. With a Sequence Actor present, the UMovieSceneEntitySystemLinker that owns FPreAnimatedCameraCutStorage is reused, which is what allows this mismatch between PreAnimatedStorage and TransientPreAnimatedStorage to surface reliably.

Steps to Reproduce
  1. Launch the attached SampleProject.
  2. Open map: Lvl_ThirdPerson.
  3. Confirm SampleSequence3 is placed in the level (this sequence is empty).
  4. Start PIE.
  5. Press key 1 to play SampleSequence1 and confirm camera blend behaves correctly.
  6. Press key 2 to play SampleSequence2 and confirm camera blend behaves correctly.
  7. Press key 3 to respawn the player.
  8. Repeat steps 5 and 6.

Expected Result: The camera blend behavior in SampleSequence2 is the same as the first playback.

Actual Result: The camera blend behavior in SampleSequence2 changes (blends/restores to an unexpected target).

Have Comments or More Details?

There's no existing public thread on this issue, so head over to Questions & Answers just mention UE-361333 in the post.

0
Login to Vote

Unresolved
ComponentUE - Anim - Sequencer
Affects Versions5.65.7
Target Fix5.8
CreatedJan 20, 2026
UpdatedJan 22, 2026
View Jira Issue