Working with Level / Master Sequence in Unreal Engine

How to work with Level Sequencer with C++ in Unreal Engine?

Sequencer, is a powerful cinematic tool used for creating, editing, and controlling complex cinematic sequences, cutscenes, and interactive storytelling experiences within a game or interactive project. It allows to create Level Sequence (single file) as well as Master Sequence that is a Sequence containing Level Sequence(s).

Level Sequences serve several purposes:

  1. Cinematic Storytelling: Level Sequences are primarily used for creating cinematic sequences and cutscenes within a game. They allow developers to craft visually engaging storytelling moments, including camera animations, character animations, and scripted events.
  2. Animation Control: They enable the precise control of animations, both for characters and objects. Animations can be keyframed and synchronized to the timeline, offering fine-grained control over character movements, facial expressions, and other animations.
  3. Camera Work: Level Sequences provide tools for crafting dynamic camera movements and shots. Cinematographers can set up camera angles, field of view, focus, and depth of field to create cinematic visuals.
  4. Audio Integration: Audio cues and soundtracks can be integrated into Level Sequences to synchronize sound effects and music with the on-screen action.
  5. Real-time Interaction: Level Sequences can also be used for real-time interaction and gameplay sequences, allowing developers to create dynamic events that respond to player actions.
  6. Non-linear Storytelling: They enable non-linear storytelling by branching sequences based on conditions or player choices, making them versatile for creating interactive narratives.
  7. Editing Environment: Unreal Engine Sequencer provides a user-friendly timeline-based editing environment with features like keyframing, blending, and visual effects, making it suitable for artists, designers, and animators.
  8. Performance Capture: Level Sequences can be used in conjunction with performance capture technologies, such as motion capture and facial animation systems, to create lifelike character animations.

Overall, Level Sequences are essential for creating engaging cinematic and storytelling experiences in Unreal Engine, bridging the gap between gameplay and narrative elements in interactive projects.

  • Prefix for Level Sequence asset files: LS_

Load Level Sequence (Helper function)

/**
 * Load Level Sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	Error message in a case of bOutSuccess == false
 * @return The loaded ULevelSequence*
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Actor From Level Sequence")
static ULevelSequence* LoadLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence

ULevelSequence* UExampleClass::LoadLevelSequence(FString LevelSequencePath, bool &bOutSuccess, FString &OutInfoMsg)
{
  ULevelSequence* LevelSequence = Cast<ULevelSequence>(StaticLoadObject(ULevelSequence::StaticClass(), nullptr, *LevelSequencePath));
  bOutSuccess = (LevelSequence != nullptr);
  if (!bOutSuccess) OutInfoMsg = FString::Printf(TEXT("Get Level Sequence at path '%s' Failed - Level Sequence isn't valid."), *LevelSequencePath);
  return LevelSequence;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
  }
);

Add / Remove Possessable Actors In Level Sequence

The code below adds already existing Actor type of component in the scene into defined Level Sequence. If the actor is not placed in the scene, use Add Spawnable Actors In Level Sequence process istead. It's very similar function that differs especially in linking at asset by it's name instead of pointing at the actor itself.

Get Actor Guid From Level Sequence

/**
 * Get actor guid from level sequence
 *
 * @param Actor		The actor to get from the level sequence
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The guid of the actor in the level sequence
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Actor From Level Sequence")
static FGuid GetActorGuidFromLevelSequence(AActor* Actor, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene

FGuid UExampleClass::GetActorGuidFromLevelSequence(AActor* Actor, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Validate Actor
	if (Actor == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Get Actor Guid From Level Sequence Failed - Actor isn't valid. '%s'"), *LevelSequencePath);
		return FGuid();
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return FGuid();
	
	// Get Actor Guid from Level Sequence
	FGuid Guid = LevelSequence->FindBindingFromObject(Actor, Actor->GetWorld());
	bOutSuccess = Guid.IsValid();
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Actor Guid From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return Guid;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add an actor into a level sequence

/**
 * Add an actor into a level sequence
 *
 * @param Actor		The actor to add in the level sequence
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 * 
 * @return The guid of the actor in the level sequence
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Actor From Level Sequence")
static FGuid AddActorIntoLevelSequence(AActor* Actor, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene

FGuid UExampleClass::AddActorIntoLevelSequence(AActor* Actor, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get Actor Guid
	FGuid Guid = GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (Guid.IsValid())
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Actor Into Level Sequence Failed - Actor is already in the level sequence. '%s'"), *LevelSequencePath);
		return Guid;
	}

	// Validate Actor
	if (Actor == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Actor Into Level Sequence Failed - Actor isn't valid. '%s'"), *LevelSequencePath);
		return FGuid();
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return FGuid();

	// Create Actor Track into Level Sequence and link it with the Actor
	Guid = Cast<UMovieSceneSequence>(LevelSequence)->CreatePossessable(Actor);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Actor Into Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return Guid;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Remove an actor from a level sequence

/**
 * Remove an actor from a level sequence
 *
 * @param Actor		The actor to remove from the level sequence
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param OutInfoMsg	More information about the action's result
 * @param return If the action was a success or not
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Actor From Level Sequence")
static bool RemoveActorFromLevelSequence(AActor* Actor, FString LevelSequencePath, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene

bool UExampleClass::RemoveActorFromLevelSequence(AActor* Actor, FString LevelSequencePath, FString& OutInfoMsg)
{
	bool bOutSuccess;
	// Get Actor Guid
	FGuid Guid = GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return false;
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return false;
	
	// Unbind Track from Actor
	LevelSequence->UnbindPossessableObjects(Guid);

	// Remove Actor Track from Level Sequence
	bOutSuccess = LevelSequence->MovieScene->RemovePossessable(Guid);

	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Remove Actor From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return bOutSuccess;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add / Remove Spawnable Actors In Level Sequence

The code below allows to place any Spawnable (not present in the level yet) Actor type of asset from Content Drawer to Level Sequence as well as Level Outliner (level).

As Spawnable, there's possible to have any number of instances of the same actor in the Level Sequence.

Get spawnable guid from level sequence based on its name

/**
 * Get spawnable guid from level sequence based on its name
 *
 * @param SpawnableName		The name of the spawnable once in the sequencer (used to identify it)
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The guid of the spawnable in the level sequence
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Spawnable From Level Sequence")
static FGuid GetSpawnableGuidFromLevelSequence(FString SpawnableName, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene

FGuid UExampleClass::GetSpawnableGuidFromLevelSequence(FString SpawnableName, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return FGuid();

	// Get Spawnable Guid from Level Sequence
	FGuid Guid = FGuid();
	for (int X = 0; X < LevelSequence->MovieScene->GetSpawnableCount(); X++)
	{
		FMovieSceneSpawnable Spawnable = LevelSequence->MovieScene->GetSpawnable(X);
		FString Name = LevelSequence->MovieScene->GetObjectDisplayName(Spawnable.GetGuid()).ToString();
		if (Name == SpawnableName)
		{
			Guid = Spawnable.GetGuid();
			break;
		}
	}

	bOutSuccess = Guid.IsValid();
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Spawnable Guid From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return Guid;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add a spawnable into a level sequence

/**
 * Add a spawnable into a level sequence
 *
 * @param SpawnableName		The name of the spawnable once in the sequencer (used to identify it)
 * @param AssetPath		The path of the asset to spawn in the level sequence: "/Game/Folder/MyStaticMesh"
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 * 
 * @return The guid of the actor in the level sequence
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Spawnable From Level Sequence")
static FGuid AddSpawnableIntoLevelSequence(FString SpawnableName, FString AssetPath, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene

FGuid UExampleClass::AddSpawnableIntoLevelSequence(FString SpawnableName, FString AssetPath, FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get Spawnable Guid
	FGuid Guid = GetSpawnableGuidFromLevelSequence(SpawnableName, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (Guid.IsValid())
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Spawnable Into Level Sequence Failed - Spawnable is already in the level sequence. '%s'"), *LevelSequencePath);
		return Guid;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return FGuid();

	// Validate asset to use as a spawnable
	UObject* SpawnableTemplate = Cast<UObject>(StaticLoadObject(UObject::StaticClass(), nullptr, *AssetPath));
	if (SpawnableTemplate == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Spawnable Into Level Sequence Failed - Spawnable template isn't valid. '%s'"), *LevelSequencePath);
		return FGuid();
	}

	// Create Spawnable Track in Level Sequence
	Guid = Cast<UMovieSceneSequence>(LevelSequence)->CreateSpawnable(SpawnableTemplate);
	if (!Guid.IsValid())
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Spawnable Into Level Sequence Failed - Cannot add asset in level sequence. '%s'"), *AssetPath);
		return FGuid();
	}

	// Rename the Spawnable to be able to find it later
	LevelSequence->MovieScene->SetObjectDisplayName(Guid, FText::FromString(SpawnableName));

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Spawnable Into Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return Guid;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Note, that each instance need to have an unique SpawnableName for option to be placed into a Level Sequence.

Remove a spawnable from a level sequence

/**
 * Remove a spawnable from a level sequence
 *
 * @param SpawnableName		The name of the spawnable in the sequencer (used to identify it)
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 * @param return	If the action was a success or not
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Spawnable From Level Sequence")
static bool RemoveSpawnableFromLevelSequence(FString SpawnableName, FString LevelSequencePath, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene

bool UExampleClass::RemoveSpawnableFromLevelSequence(FString SpawnableName, FString LevelSequencePath, FString& OutInfoMsg)
{
	// Get Spawnable Guid
	FGuid Guid = GetSpawnableGuidFromLevelSequence(SpawnableName, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return false
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return false;

	// Remove Spawnable from Level Sequence
	bool bOutSuccess = LevelSequence->MovieScene->RemoveSpawnable(Guid);
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Remove Spawnable From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return true;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add Animation In Level Sequence

/**
 * Add an animation to an actor in a level sequence
 *
 * @param Actor		The actor in the level sequence
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param AnimationPath		The path of the animation to assign to the actor: "/Game/Folder/MyAnimation"
 * @param StartFrame	Start frame of the animation section in the level sequence
 * @param EndFrame	End frame of the animation section in the level sequence
 * @param OutInfoMsg	More information about the action's result
 * @param return	If the action was a success or not
 */
UFUNCTION(BlueprintCallable, Category = "Add Animation In Level Sequence")
static bool AddAnimationInLevelSequence(AActor* Actor, FString LevelSequencePath, FString AnimationPath, int StartFrame, int EndFrame, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneSkeletalAnimationTrack.h" // MovieSceneTracks
#include "MovieSceneSection.h" // MovieScene

void UExampleClass::AddAnimationInLevelSequence(AActor* Actor, FString LevelSequencePath, FString AnimationPath, int StartFrame, int EndFrame, FString& OutInfoMsg)
{
	// Load Animation
	UAnimSequence* Animation = Cast<UAnimSequence>(StaticLoadObject(UAnimSequence::StaticClass(), nullptr, *AnimationPath));
	if (Animation == nullptr)
	{
		OutInfoMsg = FString::Printf(TEXT("Add Animation To Actor In Level Sequence Failed - Animation isn't valid. '%s'"), *AnimationPath);
		return false;
	}

	// Get Actor Guid
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return false;
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return false;

	// Find Track on which to add the Animation
	UMovieSceneSkeletalAnimationTrack* AnimTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneSkeletalAnimationTrack>(Guid);
	if (AnimTrack == nullptr)
	{
		// Create Track if doesn't exist
		AnimTrack = LevelSequence->MovieScene->AddTrack<UMovieSceneSkeletalAnimationTrack>(Guid);
		if (AnimTrack == nullptr)
		{
			OutInfoMsg = FString::Printf(TEXT("Add Animation To Actor In Level Sequence Failed - Was not able to create Track '%s'"), *LevelSequencePath);
			return false;
		}
	}

	// Calculate the Tick Value for the input frame numbers. Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	int FrameTickValue = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();

	// Add Animation on Track
	UMovieSceneSection* Section = AnimTrack->AddNewAnimation(FFrameNumber(StartFrame * FrameTickValue), Animation);
	if (Section == nullptr)
	{
		OutInfoMsg = FString::Printf(TEXT("Add Animation To Actor In Level Sequence Failed - Was not able to create Section '%s'"), *LevelSequencePath);
		return false;
	}

	// Set end frame
	if (EndFrame > StartFrame)
	{
		Section->SetEndFrame(FFrameNumber(EndFrame * FrameTickValue));
	}

	// Update the tracks in the Level Sequence
	AnimTrack->Modify();

	OutInfoMsg = FString::Printf(TEXT("Add Animation To Actor In Level Sequence Succeeded - '%s'\n'%s'"), *AnimationPath, *LevelSequencePath);
	return true;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    "MovieSceneTracks",
  }
);

Add / Remove Camera Cut Track In Level Sequence

Get a camera cut track from a level sequence

/**
 * Get a camera cut track from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 * 
 * @return The camera cut track
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Camera Cut Track From Level Sequence")
static class UMovieSceneCameraCutTrack* GetCameraCutTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCameraCutTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneCameraCutSection.h" // MovieScene
#include "Camera/CameraActor.h" // Engine

UMovieSceneCameraCutTrack* UExampleClass::GetCameraCutTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return FGuid();

	// Get the camera cut track
	UMovieSceneCameraCutTrack* CameraCutTrack = Cast<UMovieSceneCameraCutTrack>(LevelSequence->MovieScene->GetCameraCutTrack());
	bOutSuccess = CameraCutTrack != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Camera Cut Track From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return CameraCutTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    "MovieSceneTracks",
  }
);

Add a camera cut track to a level sequence

/**
 * Add a camera cut track to a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 * 
 * @return The camera cut track
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Camera Cut Track From Level Sequence")
static class UMovieSceneCameraCutTrack* AddCameraCutTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCameraCutTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneCameraCutSection.h" // MovieScene
#include "Camera/CameraActor.h" // Engine

UMovieSceneCameraCutTrack* UExampleClass::AddCameraCutTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a camera cut track in the level sequence
	UMovieSceneCameraCutTrack* CameraCutTrack = GetCameraCutTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (CameraCutTrack != nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Camera Cut Track In Level Sequence Failed - Track already in level sequence. '%s'"), *LevelSequencePath);
		return CameraCutTrack;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Add track
	CameraCutTrack = Cast<UMovieSceneCameraCutTrack>(LevelSequence->MovieScene->AddCameraCutTrack(UMovieSceneCameraCutTrack::StaticClass()));
	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Camera Cut Track In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return CameraCutTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    "MovieSceneTracks",
  }
);

Remove a camera cut track from a level sequence

	/**
 * Remove a camera cut track from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param OutInfoMsg		More information about the action's result
 * @param return	If the action was a success or not
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Camera Cut Track From Level Sequence")
static bool RemoveCameraCutTrackFromLevelSequence(FString LevelSequencePath, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCameraCutTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneCameraCutSection.h" // MovieScene
#include "Camera/CameraActor.h" // Engine

bool UExampleClass::RemoveCameraCutTrackFromLevelSequence(FString LevelSequencePath, FString& OutInfoMsg)
{
	bool bOutSuccess;

	// Check if there's a camera cut track in the level sequence
	UMovieSceneCameraCutTrack* CameraCutTrack = GetCameraCutTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (CameraCutTrack == nullptr) return false;

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return false;

	// Remove track
	LevelSequence->MovieScene->RemoveCameraCutTrack();

	OutInfoMsg = FString::Printf(TEXT("Remove Camera Cut Track From Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return true;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    "MovieSceneTracks",
  }
);

Link a camera to a camera cut track in a level sequence

/**
 * Link a camera to a camera cut track in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param CameraActor	The camera actor to link to the track
 * @param StartFrame	Start frame of the camera section in the level sequence
 * @param EndFrame	End frame of the camera section in the level sequence
 * @param OutInfoMsg	More information about the action's result
 * @param return	If the action was a success or not
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Camera Cut Track From Level Sequence")
static bool LinkCameraToCameraCutTrack(FString LevelSequencePath, class ACameraActor* CameraActor, int StartFrame, int EndFrame, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCameraCutTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneCameraCutSection.h" // MovieScene
#include "Camera/CameraActor.h" // Engine

bool UExampleClass::LinkCameraToCameraCutTrack(FString LevelSequencePath, ACameraActor* CameraActor, int StartFrame, int EndFrame, FString& OutInfoMsg)
{
	bool bOutSuccess;

	// Make sure camera is valid
	if (CameraActor == nullptr)
	{
		OutInfoMsg = FString::Printf(TEXT("Link Camera To Camera Cut Track Failed - Camera actor isn't valid. '%s'"), *LevelSequencePath);
		return false;
	}

	// Check if there's a camera cut track in the level sequence
	UMovieSceneCameraCutTrack* CameraCutTrack = GetCameraCutTrackFromLevelSequenceGetCameraCutTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (CameraCutTrack == nullptr)
	{
		OutInfoMsg = FString::Printf(TEXT("Link Camera To Camera Cut Track Failed - Camera cut track isn't valid. '%s'"), *LevelSequencePath);
		return false;
	}

	// Add camera actor in level sequence
	FGuid Guid = UExampleClass::AddActorIntoLevelSequence(CameraActor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid())
	{
		OutInfoMsg = FString::Printf(TEXT("Link Camera To Camera Cut Track Failed - Failed to add camera actor in level sequence. '%s'"), *LevelSequencePath);
		return false;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return false;

	// Calculate the Tick Value for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	int FrameTickValue = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();

	// Link camera to camera cut track
	UMovieSceneCameraCutSection* Section = CameraCutTrack->AddNewCameraCut(UE::MovieScene::FRelativeObjectBindingID(Guid), FFrameNumber(StartFrame * FrameTickValue));
	if (Section == nullptr)
	{
		OutInfoMsg = FString::Printf(TEXT("Link Camera To Camera Cut Track Failed - Was not able to create Section '%s'"), *LevelSequencePath);
		return flase;
	}

	// Set end frame
	if (EndFrame > StartFrame) Section->SetEndFrame(FFrameNumber(EndFrame * FrameTickValue));
	
	OutInfoMsg = FString::Printf(TEXT("Link Camera To Camera Cut Track Succeeded - '%s'"), *LevelSequencePath);
	return true;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    "MovieSceneTracks",
  }
);

Add / Remove Folder(s) In Level Sequence

Get a folder from a level sequence

/**
 * Get a folder from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param FolderName	The name of the folder
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 * 
 * @return The folder
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Folder From Level Sequence")
static class UMovieSceneFolder* GetFolderFromLevelSequence(FString LevelSequencePath, FString FolderName, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneFolder.h" // MovieScene

UMovieSceneFolder* UExampleClass::GetFolderFromLevelSequence(FString LevelSequencePath, FString FolderName, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;
	
	// Find existing folder
	UMovieSceneFolder* ExistingFolder = nullptr;
	for (UMovieSceneFolder* Folder : LevelSequence->MovieScene->GetRootFolders())
	{
		if (Folder->GetFolderName().ToString() == FolderName)
		{
			ExistingFolder = Folder;
			break;
		}
	}
	bOutSuccess = ExistingFolder != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Folder From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return ExistingFolder;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add a folder to a level sequence

/**
* Add a folder to a level sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param FolderName	The name of the folder
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 * 
 * @return The folder
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Folder From Level Sequence")
static class UMovieSceneFolder* AddFolderInLevelSequence(FString LevelSequencePath, FString FolderName, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneFolder.h" // MovieScene
	
UMovieSceneFolder* UExampleClass::AddFolderInLevelSequence(FString LevelSequencePath, FString FolderName, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check for existing folder
	UMovieSceneFolder* Folder = GetFolderFromLevelSequence(LevelSequencePath, FolderName, bOutSuccess, OutInfoMsg);
	if (Folder != nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Folder In Level Sequence Failed - Folder already exists. '%s'\n'%s'"), *FolderName, *LevelSequencePath);
		return Folder;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Create folder
	Folder = NewObject<UMovieSceneFolder>(LevelSequence->MovieScene, NAME_None, RF_Transactional);
	Folder->SetFolderName(*FolderName);
	
	// Add folder in level sequence
	LevelSequence->MovieScene->AddRootFolder(Folder);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Folder In Level Sequence Succeeded - '%s'\n'%s'"), *FolderName, *LevelSequencePath);
	return Folder;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Remove a folder from a level sequence

/**
 * Remove a folder from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param FolderName	The name of the folder
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Folder From Level Sequence")
static void RemoveFolderFromLevelSequence(FString LevelSequencePath, FString FolderName, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneFolder.h" // MovieScene
void UExampleClass::RemoveFolderFromLevelSequence(FString LevelSequencePath, FString FolderName, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check for existing folder
	UMovieSceneFolder* Folder = GetFolderFromLevelSequence(LevelSequencePath, FolderName, bOutSuccess, OutInfoMsg);
	if (Folder == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Remove Folder From Level Sequence Failed - Folder doesn't exist. '%s'\n'%s'"), *FolderName, *LevelSequencePath);
		return;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return;

	// Remove folder from level sequence
	LevelSequence->MovieScene->RemoveRootFolder(Folder);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Folder From Level Sequence Succeeded - '%s'\n'%s'"), *FolderName, *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Move an actor in a folder in a level sequence

/**
 * Move an actor in a folder in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param FolderName	The name of the folder
 * @param Actor		The actor to move into the folder
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Folder From Level Sequence")
static void MoveActorInFolderInLevelSequence(FString LevelSequencePath, FString FolderName, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneFolder.h" // MovieScene
void UExampleClass::MoveActorInFolderInLevelSequence(FString LevelSequencePath, FString FolderName, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get folder
	UMovieSceneFolder* Folder = GetFolderFromLevelSequence(LevelSequencePath, FolderName, bOutSuccess, OutInfoMsg);
	if (Folder == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Move Actor In Folder In Level Sequence Failed - Folder doesn't exist. '%s'\n'%s'"), *FolderName, *LevelSequencePath);
		return;
	}

	// Get actor from level sequence
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid())
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Move Actor In Folder In Level Sequence Failed - Actor is not in level sequence. '%s'"), *LevelSequencePath);
		return;
	}

	// Is the actor in the folder
	if (Folder->GetChildObjectBindings().Contains(Guid))
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Move Actor In Folder In Level Sequence Failed - Actor is already in folder. '%s'"), *LevelSequencePath);
		return;
	}

	// Move actor in folder
	Folder->AddChildObjectBinding(Guid);
	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Move Actor In Folder In Level Sequence Succeeded - '%s'\n'%s'"), *FolderName, *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Move an actor out of a folder in a level sequence

/**
 * Move an actor out of a folder in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param FolderName	The name of the folder
 * @param Actor		The actor to move out of the folder
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Add Remove Folder From Level Sequence")
static void MoveActorOutOfFolderInLevelSequence(FString LevelSequencePath, FString FolderName, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneFolder.h" // MovieScene
void UExampleClass::MoveActorOutOfFolderInLevelSequence(FString LevelSequencePath, FString FolderName, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get folder
	UMovieSceneFolder* Folder = GetFolderFromLevelSequence(LevelSequencePath, FolderName, bOutSuccess, OutInfoMsg);
	if (Folder == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Move Actor Out Of Folder In Level Sequence Failed - Folder doesn't exist. '%s'\n'%s'"), *FolderName, *LevelSequencePath);
		return;
	}

	// Get actor from level sequence
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid())
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Move Actor Out Of Folder In Level Sequence Failed - Actor is not in level sequence. '%s'"), *LevelSequencePath);
		return;
	}

	// Is the actor in the folder
	if (!Folder->GetChildObjectBindings().Contains(Guid))
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Move Actor Out Of Folder In Level Sequence Failed - Actor is not in folder. '%s'"), *LevelSequencePath);
		return;
	}
	
	// Move actor out of folder
	Folder->RemoveChildObjectBinding(Guid);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Move Actor Out Of Folder In Level Sequence Succeeded - '%s'\n'%s'"), *FolderName, *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add / Remove Shot(s) In Level Sequence

Get a shot track from a level sequence

/**
 * Get a shot track from a level sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The shot track
 */
UFUNCTION(BlueprintCallable, Category = "Shot Track in Level Sequence")
static class UMovieSceneCinematicShotTrack* GetShotTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCinematicShotTrack.h" // MovieSceneTracks

UMovieSceneCinematicShotTrack* UExampleClass::GetShotTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Get the shot track
	UMovieSceneCinematicShotTrack* ShotTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneCinematicShotTrack>();
	bOutSuccess = ShotTrack != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Shot Track From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
	return ShotTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add a shot track to a level sequence

/**
 * Add a shot track to a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The shot track
 */
UFUNCTION(BlueprintCallable, Category = "Shot Track in Level Sequence")
static class UMovieSceneCinematicShotTrack* AddShotTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCinematicShotTrack.h" // MovieSceneTracks

UMovieSceneCinematicShotTrack* UExampleClass::AddShotTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a shot track in the level sequence
	UMovieSceneCinematicShotTrack* ShotTrack = GetShotTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (ShotTrack != nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Shot Track In Level Sequence Failed - Track already in level sequence. '%s'"), *LevelSequencePath);
		return ShotTrack;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Add track
	ShotTrack = LevelSequence->MovieScene->AddTrack<UMovieSceneCinematicShotTrack>();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Shot Track In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return ShotTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a shot track from a level sequence

/**
 * Remove a shot track from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Shot Track in Level Sequence")
static void RemoveShotTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCinematicShotTrack.h" // MovieSceneTracks

void UExampleClass::RemoveShotTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a shot track in the level sequence
	UMovieSceneCinematicShotTrack* ShotTrack = GetShotTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (ShotTrack == nullptr) return;
	

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return;

	// Remove track
	LevelSequence->MovieScene->RemoveTrack(*ShotTrack);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Shot Track From Level Sequence Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Link a level sequence to a shot track in a level sequence

/**
 * Link a level sequence to a shot track in a level sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Shot	The level sequence to link to the track as a shot
 * @param StartFrame	Start frame of the shot section in the level sequence
 * @param EndFrame	End frame of the shot section in the level sequence
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Shot Track in Level Sequence")
static void LinkShotToShotTrack(FString LevelSequencePath, class ULevelSequence* Shot, int StartFrame, int EndFrame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneCinematicShotTrack.h" // MovieSceneTracks

void UExampleClass::LinkShotToShotTrack(FString LevelSequencePath, ULevelSequence* Shot, int StartFrame, int EndFrame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Make sure level sequence is valid
	if (Shot == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Link Shot To Shot Track Failed - Shot isn't valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Check if there's a shot track in the level sequence
	UMovieSceneCinematicShotTrack* ShotTrack = GetShotTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (ShotTrack == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Link Shot To Shot Track Failed - Shot track isn't valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return;

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();

	// Link shot to shot track
	UMovieSceneSubSection* Section = ShotTrack->AddSequence(Shot, FFrameNumber(StartFrame * TicksPerFrame), (EndFrame - StartFrame) * TicksPerFrame);
	
	bOutSuccess = Section != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Link Shot To Shot Track %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add / Remove Subsequence In Level Sequence

Get a subsequence track from a level sequence

/**
 * Get a subsequence track from a level sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The subsequence track
 */
UFUNCTION(BlueprintCallable, Category = "Subsequence In Level Sequence")
static class UMovieSceneSubTrack* GetSubsequenceTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneSubTrack.h" // MovieScene

UMovieSceneSubTrack* UExampleClass::GetSubsequenceTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Get the Subsequence track
	UMovieSceneSubTrack* SubsequenceTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneSubTrack>();
	bOutSuccess = SubsequenceTrack != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Subsequence Track From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);

	return SubsequenceTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add a subsequence track to a level sequence

/**
 * Add a subsequence track to a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 *
 * @return The subsequence track
 */
UFUNCTION(BlueprintCallable, Category = "Subsequence In Level Sequence")
static class UMovieSceneSubTrack* AddSubsequenceTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneSubTrack.h" // MovieScene

UMovieSceneSubTrack* UExampleClass::AddSubsequenceTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a Subsequence track in the level sequence
	UMovieSceneSubTrack* SubsequenceTrack = GetSubsequenceTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (SubsequenceTrack != nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Subsequence Track In Level Sequence Failed - Track already in level sequence. '%s'"), *LevelSequencePath);
		return SubsequenceTrack;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Add track
	SubsequenceTrack = LevelSequence->MovieScene->AddTrack<UMovieSceneSubTrack>();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Subsequence Track In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return SubsequenceTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Remove a subsequence track from a level sequence

/**
 * Remove a subsequence track from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Subsequence In Level Sequence")
static void RemoveSubsequenceTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneSubTrack.h" // MovieScene

void UExampleClass::RemoveSubsequenceTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a Subsequence track in the level sequence
	UMovieSceneSubTrack* SubsequenceTrack = GetSubsequenceTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (SubsequenceTrack == nullptr) return;
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return;

	// Remove track
	LevelSequence->MovieScene->RemoveTrack(*SubsequenceTrack);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Subsequence Track From Level Sequence Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Remove a subsequence track from a level sequence

/**
 * Link a level sequence to a subsequence track in a level sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Subsequence	The level sequence to link to the track as a subsequence
 * @param StartFrame	Start frame of the subsequence section in the level sequence
 * @param EndFrame	End frame of the subsequence section in the level sequence
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Subsequence In Level Sequence")
static void LinkSequenceToSubsequenceTrack(FString LevelSequencePath, ULevelSequence* Sequence, int StartFrame, int EndFrame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneSubTrack.h" // MovieScene

void UExampleClass::LinkSequenceToSubsequenceTrack(FString LevelSequencePath, ULevelSequence* Sequence, int StartFrame, int EndFrame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Make sure level sequence is valid
	if (Sequence == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Link Sequence To Subsequence Track Failed - Sequence isn't valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Check if there's a Subsequence track in the level sequence
	UMovieSceneSubTrack* SubsequenceTrack = GetSubsequenceTrackFromLevelSequenceGetSubsequenceTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (SubsequenceTrack == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Link Subsequence To Subsequence Track Failed - Subsequence track isn't valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return;

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();

	// Link Subsequence to Subsequence track
	UMovieSceneSubSection* Section = SubsequenceTrack->AddSequence(Sequence, FFrameNumber(StartFrame * TicksPerFrame), (EndFrame - StartFrame) * TicksPerFrame);
	
	bOutSuccess = Section != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Link Sequence To Subsequence Track %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
  }
);

Add / Remove Level Visibility Track In Level Sequence

Get a level visibility track from a level sequence

/**
 * Get a level visibility track from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The level visibility track
 */
UFUNCTION(BlueprintCallable, Category = "Level Visibility Track In Level Sequence")
static class UMovieSceneLevelVisibilityTrack* GetLevelVisibilityTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneLevelVisibilityTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneLevelVisibilitySection.h" // MovieSceneTracks

UMovieSceneLevelVisibilityTrack* UExampleClass::GetLevelVisibilityTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Get the level visibility track
	UMovieSceneLevelVisibilityTrack* LevelVisibilityTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneLevelVisibilityTrack>();
	bOutSuccess = LevelVisibilityTrack != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Level Visibility Track From Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);

	return LevelVisibilityTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add a level visibility track to a level sequence

/**
 * Add a level visibility track to a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The level visibility track
 */
UFUNCTION(BlueprintCallable, Category = "Level Visibility Track In Level Sequence")
static class UMovieSceneLevelVisibilityTrack* AddLevelVisibilityTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneLevelVisibilityTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneLevelVisibilitySection.h" // MovieSceneTracks

UMovieSceneLevelVisibilityTrack* UExampleClass::AddLevelVisibilityTrackInLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a level visibility track in the level sequence
	UMovieSceneLevelVisibilityTrack* LevelVisibilityTrack = GetLevelVisibilityTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelVisibilityTrack != nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Level Visibility Track In Level Sequence Failed - Track already in level sequence. '%s'"), *LevelSequencePath);
		return LevelVisibilityTrack;
	}

	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Add track
	LevelVisibilityTrack = LevelSequence->MovieScene->AddTrack<UMovieSceneLevelVisibilityTrack>();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Level Visibility Track In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return LevelVisibilityTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a level visibility track from a level sequence

/**
 * Remove a level visibility track from a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Level Visibility Track In Level Sequence")
static void RemoveLevelVisibilityTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneLevelVisibilityTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneLevelVisibilitySection.h" // MovieSceneTracks

void UExampleClass::RemoveLevelVisibilityTrackFromLevelSequence(FString LevelSequencePath, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a level visibility track in the level sequence
	UMovieSceneLevelVisibilityTrack* LevelVisibilityTrack = GetLevelVisibilityTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelVisibilityTrack == nullptr) return;
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return;

	// Remove track
	LevelSequence->MovieScene->RemoveTrack(*LevelVisibilityTrack);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Level Visibility Track From Level Sequence Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Link a level sequence to a level visibility track in a level sequence

/**
 * Link a level sequence to a level visibility track in a level sequence
 *
 * @param LevelSequencePath	The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param LevelName	The name of the level affected by the section
 * @param LevelVisibility	If true, the level will be set to visible
 * @param StartFrame	Start frame of the level visibility section in the level sequence
 * @param EndFrame	End frame of the level visibility section in the level sequence
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Level Visibility Track In Level Sequence")
static void AddSectionToLevelVisibilityTrack(FString LevelSequencePath, FString LevelName, bool LevelVisibility, int StartFrame, int EndFrame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieSceneLevelVisibilityTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneLevelVisibilitySection.h" // MovieSceneTracks

void UExampleClass::AddSectionToLevelVisibilityTrack(FString LevelSequencePath, FString LevelName, bool LevelVisibility, int StartFrame, int EndFrame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a level visibility track in the level sequence
	UMovieSceneLevelVisibilityTrack* LevelVisibilityTrack = GetLevelVisibilityTrackFromLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelVisibilityTrack == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Section To Level Visibility Track Failed - Level visibility track isn't valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Create section
	UMovieSceneLevelVisibilitySection* Section = Cast<UMovieSceneLevelVisibilitySection>(LevelVisibilityTrack->CreateNewSection());
	if (Section == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Section To Level Visibility Track Failed - Failed to create section. '%s'"), *LevelSequencePath);
		return;
	}

	// Set affected level and desired visibility
	Section->SetLevelNames(TArray<FName>({ *LevelName }));
	Section->SetVisibility(LevelVisibility ? ELevelVisibility::Visible : ELevelVisibility::Hidden);
	
	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = CastMovieScene->GetDisplayRate().AsDecimal();

	// Set frame range of the section
	Section->SetRange(TRange<FFrameNumber>(FFrameNumber(StartFrame * TicksPerFrame), FFrameNumber(EndFrame * TicksPerFrame)));

	// Place the section on a new row so it doesn't fight against another section
	int RowIndex = -1;
	for (UMovieSceneSection* ExistingSection : LevelVisibilityTrack->GetAllSections())
	{
		RowIndex = FMath::Max(RowIndex, ExistingSection->GetRowIndex());
	}
	Section->SetRowIndex(RowIndex + 1);

	// Add section to level visibility track
	LevelVisibilityTrack->AddSection(*Section);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Section To Level Visibility Track Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add / Remove Transform Track In Level Sequence

Get the transform track from an actor in a level sequence

/**
 * Get the transform track from an actor in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor					The actor in the level sequence
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 *
 * @return The transform track
 */
UFUNCTION(BlueprintCallable, Category = "Transform Track In Level Sequence")
static class UMovieScene3DTransformTrack* GetTransformTrackFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieScene3DTransformTrack.h" // MovieSceneTracks
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks

UMovieScene3DTransformTrack* UExampleClass::GetTransformTrackFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get actor Guid
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return nullptr;
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Get the transform track
	UMovieScene3DTransformTrack* TransformTrack = LevelSequence->MovieScene->FindTrack<UMovieScene3DTransformTrack>(Guid);

	bOutSuccess = TransformTrack != nullptr;
	FString SucceededOrFailed = bOutSuccess ? "Succeeded" : "Failed";
	OutInfoMsg = FString::Printf(TEXT("Get Transform Track From Actor In Level Sequence %s - '%s'"), *SucceededOrFailed, *LevelSequencePath);

	return TransformTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add a transform track to an actor in a level sequence

/**
 * Add a transform track to an actor in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor		The actor in the level sequence
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The transform track
 */
UFUNCTION(BlueprintCallable, Category = "Transform Track In Level Sequence")
static class UMovieScene3DTransformTrack* AddTransformTrackToActorInLevelSequence(FString LevelSequencePath, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieScene3DTransformTrack.h" // MovieSceneTracks
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks

UMovieScene3DTransformTrack* UExampleClass::AddTransformTrackToActorInLevelSequence(FString LevelSequencePath, AActor* Actor,  bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a transform track in the level sequence
	UMovieScene3DTransformTrack* TransformTrack = GetTransformTrackFromActorInLevelSequence(LevelSequencePath, Actor, bOutSuccess, OutInfoMsg);
	if (TransformTrack != nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Transform Track In Level Sequence Failed - Track already in level sequence. '%s'"), *LevelSequencePath);
		return TransformTrack;
	}

	// Get actor Guid
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return nullptr;
	
	// Load Level Sequence
	ULevelSequence* LevelSequence = UExampleClass::LoadLevelSequence(LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (LevelSequence == nullptr) return nullptr;

	// Add track
	TransformTrack = LevelSequence->MovieScene->AddTrack<UMovieScene3DTransformTrack>(Guid);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Transform Track In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return TransformTrack;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a transform track from an actor in a level sequence

/**
 * Remove a transform track from an actor in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor		The actor in the level sequence
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Transform Track In Level Sequence")
static void RemoveTransformTrackFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieScene3DTransformTrack.h" // MovieSceneTracks
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks

void UExampleClass::RemoveTransformTrackFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a transform track in the level sequence
	UMovieScene3DTransformTrack* TransformTrack = GetTransformTrackFromActorInLevelSequence(LevelSequencePath, Actor, bOutSuccess, OutInfoMsg);
	if (TransformTrack == nullptr) return;
	
	// Load level sequence
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(StaticLoadObject(ULevelSequence::StaticClass(), nullptr, *LevelSequencePath));

	// Remove track
	LevelSequence->MovieScene->RemoveTrack(*TransformTrack);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Transform Track From Actor In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Get the transform section from an actor in a level sequence

/**
 * Get the transform section from an actor in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor		The actor in the level sequence
 * @param SectionIndex	Index of the section
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The transform section
 */
UFUNCTION(BlueprintCallable, Category = "Transform Track In Level Sequence")
static class UMovieScene3DTransformSection* GetTransformSectionFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, int SectionIndex, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieScene3DTransformTrack.h" // MovieSceneTracks
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks

UMovieScene3DTransformSection* UExampleClass::GetTransformSectionFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, int SectionIndex, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a transform track in the level sequence
	UMovieScene3DTransformTrack* TransformTrack = GetTransformTrackFromActorInLevelSequence(LevelSequencePath, Actor, bOutSuccess, OutInfoMsg);
	if (TransformTrack == nullptr) return nullptr;
	
	// Get all sections
	TArray<UMovieSceneSection*> AllSections = TransformTrack->GetAllSections();

	// Make sure index is valid
	if (SectionIndex < 0 || SectionIndex >= AllSections.Num())
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Get Transform Section From Actor In Level Sequence Failed - Section index is invalid. '%s'"), *LevelSequencePath);
		return nullptr;
	}

	// Return section
	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Get Transform Section From Actor In Level Sequence Succeeded - '%s'"), *LevelSequencePath);

	return Cast<UMovieScene3DTransformSection>(AllSections[SectionIndex]);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add a transform section to an actor in a level sequence

#include "Evaluation/Blending/MovieSceneBlendType.h" // MovieScene
/**
 * Add a transform section to an actor in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor		The actor in the level sequence
 * @param StartFrame	Start frame of the section
 * @param EndFrame	End frame of the section
 * @param BlendType	Blend type of the section
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 *
 * @return The transform section
 */
UFUNCTION(BlueprintCallable, Category = "Transform Track In Level Sequence")
static class UMovieScene3DTransformSection* AddTransformSectionToActorInLevelSequence(FString LevelSequencePath, AActor* Actor, int StartFrame, int EndFrame, EMovieSceneBlendType BlendType, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieScene3DTransformTrack.h" // MovieSceneTracks
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks

UMovieScene3DTransformSection* UExampleClass::AddTransformSectionToActorInLevelSequence(FString LevelSequencePath, AActor* Actor, int StartFrame, int EndFrame, EMovieSceneBlendType BlendType, bool& bOutSuccess, FString& OutInfoMsg) {
	// Check if there's a transform track in the level sequence
	UMovieScene3DTransformTrack* TransformTrack = GetTransformTrackFromActorInLevelSequence(LevelSequencePath, Actor, bOutSuccess, OutInfoMsg);
	if (TransformTrack == nullptr) return nullptr;
	
	// Create section
	UMovieScene3DTransformSection* TransformSection = Cast<UMovieScene3DTransformSection>(TransformTrack->CreateNewSection());
	if (TransformSection == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Transform Section To Actor In Level Sequence Failed - Failed to create section. '%s'"), *LevelSequencePath);
		return nullptr;
	}

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(StaticLoadObject(ULevelSequence::StaticClass(), nullptr, *LevelSequencePath));
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();

	// Set frame range of the section
	TransformSection->SetRange(TRange<FFrameNumber>(FFrameNumber(StartFrame * TicksPerFrame), FFrameNumber(EndFrame * TicksPerFrame)));

	// Set blend type
	TransformSection->SetBlendType(BlendType);

	// Place the section on a new row so it doesn't fight against another section
	int RowIndex = -1;
	for (UMovieSceneSection* ExistingSection : TransformTrack->GetAllSections())
	{
		RowIndex = FMath::Max(RowIndex, ExistingSection->GetRowIndex());
	}
	TransformSection->SetRowIndex(RowIndex + 1);
	
	// Add section to track
	TransformTrack->AddSection(*TransformSection);

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Transform Section To Actor In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
	return TransformSection;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a transform section from an actor in a level sequence

/**
 * Remove a transform section from an actor in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor		The actor in the level sequence
 * @param SectionIndex	Index of the section
 * @param bOutSuccess	If the action was a success or not
 * @param OutInfoMsg	More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Transform Track In Level Sequence")
static void RemoveTransformSectionFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, int SectionIndex, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "Tracks/MovieScene3DTransformTrack.h" // MovieSceneTracks
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks

void UExampleClass::RemoveTransformSectionFromActorInLevelSequence(FString LevelSequencePath, AActor* Actor, int SectionIndex, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Check if there's a transform track in the level sequence
	UMovieScene3DTransformSection* TransformSection = GetTransformSectionFromActorInLevelSequence(LevelSequencePath, Actor, SectionIndex, bOutSuccess, OutInfoMsg);
	if (TransformSection == nullptr) return;
	
	// Get track
	UMovieScene3DTransformTrack* TransformTrack = GetTransformTrackFromActorInLevelSequence(LevelSequencePath, Actor, bOutSuccess, OutInfoMsg);

	// Remove section
	TransformTrack->RemoveSection(*TransformSection);

	// Refresh level sequence
	TransformTrack->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Transform Section From Actor In Level Sequence Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add / Remove Keyframe to / from transform section In Level Sequence

Add a keyframe to a transform section in a level sequence

/**
 * Add a keyframe to a transform section in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor					The actor in the level sequence
 * @param SectionIndex			Index of the section
 * @param Frame					Frame number
 * @param Transform				Value to apply to the keys
 * @param KeyInterpolation		Interpolation of the keys: 0=Cubic, 1=Linear, 2=Constant
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Add Transform Keyframe In Level Sequence")
static void AddTransformKeyframe(FString LevelSequencePath, AActor* Actor, int SectionIndex, int Frame, FTransform Transform, int KeyInterpolation, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneDoubleChannel.h" // MovieScene

void UExampleClass::AddTransformKeyframe(FString LevelSequencePath, AActor* Actor, int SectionIndex, int Frame, FTransform Transform, int KeyInterpolation, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get the section
	UMovieScene3DTransformSection* Section = UExampleClass::GetTransformSectionFromActorInLevelSequence(LevelSequencePath, Actor, SectionIndex, bOutSuccess, OutInfoMsg);

	if (Section == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Transform Keyframe Failed - Transform section is not valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Remove previous keyframe if there's one
	RemoveTransformKeyframe(LevelSequencePath, Actor, SectionIndex, Frame, bOutSuccess, OutInfoMsg);

	// Location
	AddKeyframeToDoubleChannel(Section, 0, Frame, Transform.GetLocation().X, KeyInterpolation, bOutSuccess, OutInfoMsg);
	AddKeyframeToDoubleChannel(Section, 1, Frame, Transform.GetLocation().Y, KeyInterpolation, bOutSuccess, OutInfoMsg);
	AddKeyframeToDoubleChannel(Section, 2, Frame, Transform.GetLocation().Z, KeyInterpolation, bOutSuccess, OutInfoMsg);
	// Rotation	
	AddKeyframeToDoubleChannel(Section, 3, Frame, Transform.Rotator().Roll, KeyInterpolation, bOutSuccess, OutInfoMsg);
	AddKeyframeToDoubleChannel(Section, 4, Frame, Transform.Rotator().Pitch, KeyInterpolation, bOutSuccess, OutInfoMsg);
	AddKeyframeToDoubleChannel(Section, 5, Frame, Transform.Rotator().Yaw, KeyInterpolation, bOutSuccess, OutInfoMsg);
	// Scale
	AddKeyframeToDoubleChannel(Section, 6, Frame, Transform.GetScale3D().X, KeyInterpolation, bOutSuccess, OutInfoMsg);
	AddKeyframeToDoubleChannel(Section, 7, Frame, Transform.GetScale3D().Y, KeyInterpolation, bOutSuccess, OutInfoMsg);
	AddKeyframeToDoubleChannel(Section, 8, Frame, Transform.GetScale3D().Z, KeyInterpolation, bOutSuccess, OutInfoMsg);

	OutInfoMsg = bOutSuccess ? FString::Printf(TEXT("Add Transform Keyframe Succeeded - '%s'"), *LevelSequencePath) : OutInfoMsg;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a keyframe from a transform section in a level sequence

/**
 * Remove a keyframe from a transform section in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor					The actor in the level sequence
 * @param SectionIndex			Index of the section
 * @param Frame					Frame number
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Add Transform Keyframe In Level Sequence")
static void RemoveTransformKeyframe(FString LevelSequencePath, AActor* Actor, int SectionIndex, int Frame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneDoubleChannel.h" // MovieScene

void UExampleClass::RemoveTransformKeyframe(FString LevelSequencePath, AActor* Actor, int SectionIndex, int Frame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get the section
	UMovieScene3DTransformSection* Section = UExampleClass::GetTransformSectionFromActorInLevelSequence(LevelSequencePath, Actor, SectionIndex, bOutSuccess, OutInfoMsg);
	if (Section == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Remove Transform Keyframe Failed - Transform section is not valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Location
	RemoveKeyframeFromDoubleChannel(Section, 0, Frame, bOutSuccess, OutInfoMsg);
	RemoveKeyframeFromDoubleChannel(Section, 1, Frame, bOutSuccess, OutInfoMsg);
	RemoveKeyframeFromDoubleChannel(Section, 2, Frame, bOutSuccess, OutInfoMsg);
	// Rotation	
	RemoveKeyframeFromDoubleChannel(Section, 3, Frame, bOutSuccess, OutInfoMsg);
	RemoveKeyframeFromDoubleChannel(Section, 4, Frame, bOutSuccess, OutInfoMsg);
	RemoveKeyframeFromDoubleChannel(Section, 5, Frame, bOutSuccess, OutInfoMsg);
	// Scale
	RemoveKeyframeFromDoubleChannel(Section, 6, Frame, bOutSuccess, OutInfoMsg);
	RemoveKeyframeFromDoubleChannel(Section, 7, Frame, bOutSuccess, OutInfoMsg);
	RemoveKeyframeFromDoubleChannel(Section, 8, Frame, bOutSuccess, OutInfoMsg);

	OutInfoMsg = bOutSuccess ? FString::Printf(TEXT("Remove Transform Keyframe Succeeded - '%s'"), *LevelSequencePath) : OutInfoMsg;
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add a keyframe to a double channel in a level sequence

/**
 * Add a keyframe to a double channel in a level sequence
 *
 * @param Section				Section to modify
 * @param ChannelIndex			Index of the channel
 * @param Frame					Frame number
 * @param Value					Value to apply to the keyframe
 * @param KeyInterpolation		Interpolation of the keys: 0=Cubic, 1=Linear, 2=Constant
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Add Transform Keyframe In Level Sequence")
static void AddKeyframeToDoubleChannel(UMovieSceneSection* Section, int ChannelIndex, int Frame, double Value, int KeyInterpolation, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneDoubleChannel.h" // MovieScene

void UExampleClass::AddKeyframeToDoubleChannel(UMovieSceneSection* Section, int ChannelIndex, int Frame, double Value, int KeyInterpolation, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Make sure section is valid
	if (Section == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Keyframe To Double Channel Failed - Section is not valid."));
		return;
	}

	// Get the channel
	FMovieSceneDoubleChannel* Channel = Section->GetChannelProxy().GetChannel<FMovieSceneDoubleChannel>(ChannelIndex);
	if (Channel == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Keyframe To Double Channel Failed - Channel is not valid."));
		return;
	}

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(Section->GetOutermostObject());;
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	// Add key to channel
	if (KeyInterpolation == 0)
	{
		Channel->AddCubicKey(FrameNumber, Value);
	}
	else if (KeyInterpolation == 1)
	{
		Channel->AddLinearKey(FrameNumber, Value);
	}
	else
	{
		Channel->AddConstantKey(FrameNumber, Value);
	}

	// Refresh section
	Section->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Keyframe To Double Channel Succeeded"));
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a keyframe from a double channel in a level sequence

/**
 * Remove a keyframe from a double channel in a level sequence
 *
 * @param Section				Section to modify
 * @param ChannelIndex			Index of the channel
 * @param Frame					Frame number
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Add Transform Keyframe In Level Sequence")
static void RemoveKeyframeFromDoubleChannel(UMovieSceneSection* Section, int ChannelIndex, int Frame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneDoubleChannel.h" // MovieScene

void UExampleClass::RemoveKeyframeFromDoubleChannel(UMovieSceneSection* Section, int ChannelIndex, int Frame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Make sure section is valid
	if (Section == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Remove Keyframe From Double Channel Failed - Section is not valid."));
		return;
	}

	// Get the channel
	FMovieSceneDoubleChannel* Channel = Section->GetChannelProxy().GetChannel<FMovieSceneDoubleChannel>(ChannelIndex);
	if (Channel == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Remove Keyframe From Double Channel Failed - Channel is not valid."));
		return;
	}

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(Section->GetOutermostObject());;
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	// Find key we want to remove
	TArray<FFrameNumber> UnusedKeyTimes;
	TArray<FKeyHandle> KeyHandles;
	Channel->GetKeys(TRange<FFrameNumber>(FrameNumber, FrameNumber), &UnusedKeyTimes, &KeyHandles);

	// Remove key
	Channel->DeleteKeys(KeyHandles);

	// Refresh section
	Section->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Keyframe From Double Channel Succeeded"));
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // New Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Modify a keyframe interpolation in a transform section in a level sequence

#include "Curves/RealCurve.h" // Engine
/**
 * Modify a keyframe interpolation in a transform section in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor					The actor in the level sequence
 * @param SectionIndex			Index of the section in the transform track
 * @param ChannelIndex			Index of the channel in the section
 * @param Frame					Frame number
 * @param Value					Value to apply to the key
 * @param InterpMode			Interpolation of the key: 0=Cubic, 1=Linear, 2=Constant
 * @param TangentMode			Tangents of the key: 0=Auto, 1=User, 2=Break
 * @param ArriveTangent			Arrive tangent of the key
 * @param LeaveTangent			Leave tangent of the key
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg			More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Set Keyframe Interpolation In Level Sequence")
static void SetKeyframeInterpolationInTransformTrack(FString LevelSequencePath, AActor* Actor, int SectionIndex, int ChannelIndex, int Frame, double Value, ERichCurveInterpMode InterpMode, ERichCurveTangentMode TangentMode, float ArriveTangent, float LeaveTangent, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Sections/MovieScene3DTransformSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneDoubleChannel.h" // MovieScene

void UExampleClass::SetKeyframeInterpolationInTransformTrack(FString LevelSequencePath, AActor* Actor, int SectionIndex, int ChannelIndex, int Frame, double Value, ERichCurveInterpMode InterpMode, ERichCurveTangentMode TangentMode, float ArriveTangent, float LeaveTangent, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get the section
	UMovieScene3DTransformSection* Section = UExampleClass::GetTransformSectionFromActorInLevelSequence(LevelSequencePath, Actor, SectionIndex, bOutSuccess, OutInfoMsg);
	if (Section == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Set Keyframe Interpolation In Double Channel Failed - Transform section is not valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Get the channel
	FMovieSceneDoubleChannel* Channel = Section->GetChannelProxy().GetChannel<FMovieSceneDoubleChannel>(ChannelIndex);
	if (Channel == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Set Keyframe Interpolation In Double Channel Failed - Channel is not valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(Section->GetOutermostObject());;
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	// Find key(s) we want to modify
	TArray<FFrameNumber> UnusedKeyTimes;
	TArray<FKeyHandle> KeyHandles;
	Channel->GetKeys(TRange<FFrameNumber>(FrameNumber, FrameNumber), &UnusedKeyTimes, &KeyHandles);

	for (FKeyHandle Handle : KeyHandles)
	{
		// Find index
		int Index = Channel->GetData().GetIndex(Handle);
		// Apply settings
		Channel->GetData().GetValues()[Index].Value = Value;
		Channel->GetData().GetValues()[Index].InterpMode = InterpMode;
		Channel->GetData().GetValues()[Index].TangentMode = TangentMode;

		if (TangentMode == ERichCurveTangentMode::RCTM_Auto)
		{
			// When auto, should keep the tangents to 0 so Unreal controls them
			Channel->GetData().GetValues()[Index].Tangent.ArriveTangent = 0.0f;
			Channel->GetData().GetValues()[Index].Tangent.LeaveTangent = 0.0f;
		}
		else if (TangentMode == ERichCurveTangentMode::RCTM_User)
		{
			// When User, both tangents should be the same, in this case, we're using the ArriveTangent only
			Channel->GetData().GetValues()[Index].Tangent.ArriveTangent = ArriveTangent;
			Channel->GetData().GetValues()[Index].Tangent.LeaveTangent = ArriveTangent;
		}
		else if (TangentMode == ERichCurveTangentMode::RCTM_Break)
		{
			// When Brek, we can do anything we want
			Channel->GetData().GetValues()[Index].Tangent.ArriveTangent = ArriveTangent;
			Channel->GetData().GetValues()[Index].Tangent.LeaveTangent = LeaveTangent;
		}
	}

	// Refresh section
	Section->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Set Keyframe Interpolation In Double Channel Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // Required Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Visibility Keyframe In Level Sequence with C++

Add a keyframe to a Visibility track

#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
 * Add a keyframe to a Visibility track in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor					The actor in the level sequence
 * @param Frame					Frame number
 * @param Visibility			Value to apply to the key
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Visibility Keyframe In Level Sequence")
static void AddVisibilityKeyframe(FString LevelSequencePath, AActor* Actor, int Frame, bool Visibility, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Tracks/MovieSceneVisibilityTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneBoolSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneBoolChannel.h" // MovieScene

void UExampleClass::AddVisibilityKeyframe(FString LevelSequencePath, AActor* Actor, int Frame, bool Visibility, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Remove previous keyframe if there's one
	RemoveVisibilityKeyframe(LevelSequencePath, Actor, Frame, bOutSuccess, OutInfoMsg);

	// Get actor Guid
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	
	if (!Guid.IsValid()) return;
	
	// Load level sequence & calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(StaticLoadObject(ULevelSequence::StaticClass(), nullptr, *LevelSequencePath));
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	// Get the visibility track
	UMovieSceneVisibilityTrack* VisibilityTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneVisibilityTrack>(Guid); 
	// Or create it if it doesn't exist
	if (VisibilityTrack == nullptr) VisibilityTrack = LevelSequence->MovieScene->AddTrack<UMovieSceneVisibilityTrack>(Guid);
	
	// Get the visibility section. Or create it if it doesn't exist
	bool bSectionAdded = false;
	UMovieSceneBoolSection* BoolSection = Cast<UMovieSceneBoolSection>(VisibilityTrack->FindOrAddSection(FrameNumber, bSectionAdded));
	if (bSectionAdded) BoolSection->SetRange(TRange<FFrameNumber>::All());
	
	// Get the channel
	FMovieSceneBoolChannel* Channel = BoolSection->GetChannelProxy().GetChannel<FMovieSceneBoolChannel>(0);

	// Add keyframe
	Channel->AddKeys({ FrameNumber }, { Visibility });

	// Refresh level sequence
	VisibilityTrack->Modify();
	BoolSection->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Visibility Keyframe Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // Required Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Remove a keyframe from a Visibility track in a level sequence

#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
 * Remove a keyframe from a Visibility track in a level sequence
 *
 * @param LevelSequencePath		The path of the level sequence asset: "/Game/Folder/MyLevelSequence"
 * @param Actor					The actor in the level sequence
 * @param Frame					Frame number
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg		More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon - Visibility Keyframe In Level Sequence")
static void RemoveVisibilityKeyframe(FString LevelSequencePath, AActor* Actor, int Frame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Tracks/MovieSceneVisibilityTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneBoolSection.h" // MovieSceneTracks
#include "Channels/MovieSceneChannelProxy.h" // MovieScene
#include "Channels/MovieSceneBoolChannel.h" // MovieScene

void UExampleClass::RemoveVisibilityKeyframe(FString LevelSequencePath, AActor* Actor, int Frame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Get actor Guid
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequencePath, bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return;
	
	// Load level sequence & calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	ULevelSequence* LevelSequence = Cast<ULevelSequence>(StaticLoadObject(ULevelSequence::StaticClass(), nullptr, *LevelSequencePath));
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	// Get the visibility track
	UMovieSceneVisibilityTrack* VisibilityTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneVisibilityTrack>(Guid);
	if (VisibilityTrack == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Remove Visibility Keyframe Failed - Visibility track is not valid. '%s'"), *LevelSequencePath);
		return;	
	}

	// Get the visibility section.
	UMovieSceneBoolSection* BoolSection = Cast<UMovieSceneBoolSection>(VisibilityTrack->FindSection(FrameNumber));
	if (BoolSection == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Remove Visibility Keyframe Failed - Visibility section is not valid. '%s'"), *LevelSequencePath);
		return;
	}

	// Get the channel
	FMovieSceneBoolChannel* Channel = BoolSection->GetChannelProxy().GetChannel<FMovieSceneBoolChannel>(0);

	// Find key we want to remove
	TArray<FFrameNumber> UnusedKeyTimes;
	TArray<FKeyHandle> KeyHandles;
	Channel->GetKeys(TRange<FFrameNumber>(FrameNumber, FrameNumber), &UnusedKeyTimes, &KeyHandles);

	// Remove key
	Channel->DeleteKeys(KeyHandles);

	// Refresh section
	VisibilityTrack->Modify();
	BoolSection->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Remove Visibility Keyframe Succeeded - '%s'"), *LevelSequencePath);
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject",
    "Engine", 

    // Required Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add Material Parameter Collection Keyframe In Level Sequence

The code below allows to modify material of any linked Mesh or Actor.

#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
	 * Add a keyframe to a Mpc float or color section in a level sequence
	 *
	 * @param LevelSequence		The level sequence asset
	 * @param Frame				Frame number
	 * @param Collection		Material parameter collection asset
	 * @param Parameter			Name of the material parameter
	 * @param FloatValue		Value to apply to the float parameter
	 * @param ColorValue		Value to apply to the color parameter
	 * @param bColor			If true, apply ColorValue, else apply FloatValue
	 * @param bOutSuccess		If the action was a success or not
	 * @param OutInfoMsg		More information about the action's result
	 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon -  Add Material Parameter Collection Keyframe In Level Sequence")
static void AddMpcKeyframe(class ULevelSequence* LevelSequence, class UMaterialParameterCollection* Collection, int Frame, FString Parameter, float FloatValue, FLinearColor ColorValue, bool bColor, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene
#include "Tracks/MovieSceneMaterialParameterCollectionTrack.h" // MovieSceneTracks
#include "Materials/MaterialParameterCollection.h" // Engine

void UExampleClass::AddMpcKeyframe(ULevelSequence* LevelSequence, UMaterialParameterCollection* Collection, int Frame, FString Parameter, float FloatValue, FLinearColor ColorValue, bool bColor, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Validate Level Sequence
	if (LevelSequence == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Mpc Float Keyframe Failed - Level Sequence is not valid"));
		return;
	}

	// Validate MPC
	if (Collection == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add Mpc Float Keyframe Failed - Material Parameter Collection is not valid"));
		return;
	}

	// Get the Mpc track
	TArray<UMovieSceneTrack*> Tracks = LevelSequence->MovieScene->GetTracks();
	UMovieSceneMaterialParameterCollectionTrack* MpcTrack = nullptr;
	for (UMovieSceneTrack* Track : Tracks)
	{
		UMovieSceneMaterialParameterCollectionTrack* MpcT = Cast<UMovieSceneMaterialParameterCollectionTrack>(Track);
		if (MpcT != nullptr && MpcT->MPC == Collection)
		{ 
			MpcTrack = MpcT;
			break;
		}
	}

	// Or create it if it doesn't exist
	if (MpcTrack == nullptr)
	{
		MpcTrack = LevelSequence->MovieScene->AddTrack<UMovieSceneMaterialParameterCollectionTrack>();
		MpcTrack->MPC = Collection;
		MpcTrack->SetDisplayName(FText::FromString(Collection->GetName()));
	}
	
	// Get section or create if if it doesn't exist
	UMovieSceneSection* MpcSection = nullptr;
	if (MpcTrack->GetAllSections().Num() > 0)
	{
		MpcSection = MpcTrack->GetAllSections()[0];
	}
	else
	{
		MpcSection = MpcTrack->CreateNewSection();
		MpcSection->SetRange(TRange<FFrameNumber>::All());
		MpcTrack->AddSection(*MpcSection);
	}

	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	if (bColor)
	{
		// Add Color Keyframe
		MpcTrack->AddColorParameterKey(*Parameter, FrameNumber, ColorValue);
	}
	else
	{
		// Add Scalar Keyframe
		MpcTrack->AddScalarParameterKey(*Parameter, FrameNumber, FloatValue);
	}

	// Refresh level sequence
	MpcTrack->Modify();
	MpcSection->Modify();

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add Mpc Keyframe Succeeded"));
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // Required Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Add BP Variables Keyframe In Level Sequence

The code below allows to add and update the value of Blueprint variables (exposed to cinematics) for any linked Blueprint Actor in the Level Sequence.

#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
 * Add a keyframe to a few BP actor variables in a level sequence
 *
 * @param LevelSequence			The level sequence asset
 * @param Actor					The actor in the level sequence
 * @param Frame					Frame number
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg			More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon -  Add Material Parameter Collection Keyframe In Level Sequence")
static void AddBpVariableKeyframe(class ULevelSequence* LevelSequence, AActor* Actor, int Frame, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequence.h" // LevelSequence
#include "MovieScene.h" // MovieScene
#include "MovieSceneSection.h" // MovieScene

#include "Tracks/MovieSceneBoolTrack.h" // MovieSceneTracks
#include "Sections/MovieSceneBoolSection.h" // MovieSceneTracks
#include "Channels/MovieSceneBoolChannel.h" // MovieScene

#include "Tracks/MovieSceneFloatTrack.h "// MovieSceneTracks
#include "Sections/MovieSceneFloatSection.h" // MovieSceneTracks
#include "Channels/MovieSceneFloatChannel.h" // MovieScene

#include "Tracks/MovieSceneByteTrack.h "// MovieSceneTracks
#include "Sections/MovieSceneByteSection.h" // MovieSceneTracks
#include "Channels/MovieSceneByteChannel.h" // MovieScene

void UExampleClass::AddBpVariableKeyframe(ULevelSequence* LevelSequence, AActor* Actor, int Frame, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Validate Level Sequence
	if (LevelSequence == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Add BP Variable Keyframe Failed - Level Sequence is not valid"));
		return;
	}
 
	// Get actor Guid
	FGuid Guid = UExampleClass::GetActorGuidFromLevelSequence(Actor, LevelSequence->GetPathName(), bOutSuccess, OutInfoMsg);
	if (!Guid.IsValid()) return;
	
	// Calculate the amount of Ticks Per Frame for the input frame numbers. 
	// Level Sequence works in ticks, not in frames and quantity of ticks varies based on TickResolution and DisplayRate.
	int TicksPerFrame = LevelSequence->MovieScene->GetTickResolution().AsDecimal() / LevelSequence->MovieScene->GetDisplayRate().AsDecimal();
	FFrameNumber FrameNumber = FFrameNumber(Frame * TicksPerFrame);

	// Bool variable
	{
		// Get variable track 
		UMovieSceneBoolTrack* Track = LevelSequence->MovieScene->FindTrack<UMovieSceneBoolTrack>(Guid, "MyBpBoolVariableName");
		// Or create it if it doesn't exist
		if (Track == nullptr)
		{
			Track = LevelSequence->MovieScene->AddTrack<UMovieSceneBoolTrack>(Guid);
			Track->SetPropertyNameAndPath("MyBpBoolVariableName", "MyBpBoolVariableName");
			// To find the PropertyName & PropertyPath, add a breakpoint in UMovieScenePropertyTrack::SetPropertyNameAndPath and add the track manually in editor
		}

		// Get the section or create it if it doesn't exist
		bool bSectionAdded = false;
		UMovieSceneBoolSection* Section = Cast<UMovieSceneBoolSection>(Track->FindOrAddSection(FrameNumber, bSectionAdded));
		if (bSectionAdded) Section->SetRange(TRange<FFrameNumber>::All());
		
		// Get the channel
		FMovieSceneBoolChannel* Channel = Section->GetChannelProxy().GetChannel<FMovieSceneBoolChannel>(0);

		// Add keyframe
		Channel->AddKeys({ FrameNumber }, { FMath::RandBool() });

		// Refresh level sequence
		Track->Modify();
		Section->Modify();
	}
	// Float variable
	{
		// Get variable track 
		UMovieSceneFloatTrack* Track = LevelSequence->MovieScene->FindTrack<UMovieSceneFloatTrack>(Guid, "MyBpFloatVariableName");
		// Or create it if it doesn't exist
		if (Track == nullptr)
		{
			Track = LevelSequence->MovieScene->AddTrack<UMovieSceneFloatTrack>(Guid);
			Track->SetPropertyNameAndPath("MyBpFloatVariableName", "MyBpFloatVariableName");
		}

		// Get the section or create it if it doesn't exist
		bool bSectionAdded = false;
		UMovieSceneFloatSection* Section = Cast<UMovieSceneFloatSection>(Track->FindOrAddSection(FrameNumber, bSectionAdded));
		if (bSectionAdded) Section->SetRange(TRange<FFrameNumber>::All());
		
		// Get the channel
		FMovieSceneFloatChannel* Channel = Section->GetChannelProxy().GetChannel<FMovieSceneFloatChannel>(0);

		// Add keyframe
		Channel->AddLinearKey(FrameNumber, FMath::RandRange(-100.0f, 100.0f));

		// Refresh level sequence
		Track->Modify();
		Section->Modify();
	}
	// Byte variable
	{
		// Get variable track 
		UMovieSceneByteTrack* Track = LevelSequence->MovieScene->FindTrack<UMovieSceneByteTrack>(Guid, "MyBpByteVariableName");
		// Or create it if it doesn't exist
		if (Track == nullptr)
		{
			Track = LevelSequence->MovieScene->AddTrack<UMovieSceneByteTrack>(Guid);
			Track->SetPropertyNameAndPath("MyBpByteVariableName", "MyBpByteVariableName");
		}

		// Get the section or create it if it doesn't exist
		bool bSectionAdded = false;
		UMovieSceneByteSection* Section = Cast<UMovieSceneByteSection>(Track->FindOrAddSection(FrameNumber, bSectionAdded));
		if (bSectionAdded) Section->SetRange(TRange<FFrameNumber>::All());
		
		// Get the channel
		FMovieSceneByteChannel* Channel = Section->GetChannelProxy().GetChannel<FMovieSceneByteChannel>(0);

		// Add keyframe
		Channel->AddKeys({ FrameNumber }, { uint8(FMath::RandRange(0, 7)) });

		// Refresh level sequence
		Track->Modify();
		Section->Modify();
	}

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Add BP Variable Keyframe Succeeded"));
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // Required Modules
    "LevelSequence",
    "MovieScene",
    MovieSceneTracks,
  }
);

Start the Render of a Level Sequence

#include "Kismet/BlueprintFunctionLibrary.h" // Engine
/**
 * Start a render process
 *
 * @param LevelSequence			The level sequence asset to render
 * @param OutputDirectory		Where to save the output: "C:/Temp/MyRenderFolder"
 * @param bRenderAsMovie		If true, will render a movie. Otherwise, will render individual frames
 * @param bOutSuccess			If the action was a success or not
 * @param OutInfoMsg			More information about the action's result
 */
UFUNCTION(BlueprintCallable, Category = "Alex Quevillon -  Start the Render of a Level Sequence")
static void StartLevelSequenceRender(class ULevelSequence* LevelSequence, FString OutputDirectory, bool bRenderAsMovie, bool& bOutSuccess, FString& OutInfoMsg);
#include "LevelSequenceActor.h" // LevelSequence
#include "SequencerTools.h" // SequencerScriptingEditor
#include "AutomatedLevelSequenceCapture.h" // MovieSceneTools
#include "Protocols/ImageSequenceProtocol.h" // MovieSceneCapture
#include "Protocols/VideoCaptureProtocol.h" // MovieSceneCapture & AVIWriter
#include "Protocols/AudioCaptureProtocol.h" // MovieSceneCapture

void UExampleClass::StartLevelSequenceRender(ULevelSequence* LevelSequence, FString OutputDirectory, bool bRenderAsMovie, bool& bOutSuccess, FString& OutInfoMsg)
{
	// Validate Level Sequence
	if (LevelSequence == nullptr)
	{
		bOutSuccess = false;
		OutInfoMsg = FString::Printf(TEXT("Start Level Sequence Render Failed - Level Sequence is not valid"));
		return;
	}

	// Create Capture Settings (Same as Render Movie Settings window)
	UAutomatedLevelSequenceCapture* Capture = NewObject<UAutomatedLevelSequenceCapture>();
	
	// Level sequence
	Capture->LevelSequenceAsset = LevelSequence;

	// Output directory
	FDirectoryPath DirPath;
	DirPath.Path = OutputDirectory;
	Capture->Settings.OutputDirectory = DirPath;

	// Render type
	if (bRenderAsMovie)
	{
		Capture->SetImageCaptureProtocolType(UVideoCaptureProtocol::StaticClass());
		Cast<UVideoCaptureProtocol>(Capture->ImageCaptureProtocol)->bUseCompression = true;
		Cast<UVideoCaptureProtocol>(Capture->ImageCaptureProtocol)->CompressionQuality = 75;

		// Possible Classes: UNullAudioCaptureProtocol, UMasterAudioSubmixCaptureProtocol
		Capture->SetAudioCaptureProtocolType(UNullAudioCaptureProtocol::StaticClass());
	}
	else
	{
		// Possible Classes: UImageSequenceProtocol_JPG, UImageSequenceProtocol_PNG, UImageSequenceProtocol_BMP, UImageSequenceProtocol_EXR
		Capture->SetImageCaptureProtocolType(UImageSequenceProtocol_PNG::StaticClass());
		Cast<UImageSequenceProtocol_PNG>(Capture->ImageCaptureProtocol)->CompressionQuality = 75;
	}


	// UMovieSceneCapture
	Capture->bUseSeparateProcess = true; // If true, set bCloseEditorWhenCaptureStarts, AdditionalCommandLineArguments & InheritedCommandLineArguments.
	Capture->bCloseEditorWhenCaptureStarts = false;
	Capture->AdditionalCommandLineArguments = "-NOSCREENMESSAGES";
	Capture->InheritedCommandLineArguments = "-skipcompile";

	// FMovieSceneCaptureSettings
	Capture->Settings.GameModeOverride = nullptr;
	Capture->Settings.OutputFormat = "{shot}_{frame}";
	Capture->Settings.bOverwriteExisting = true;
	Capture->Settings.bUseRelativeFrameNumbers = false;
	Capture->Settings.HandleFrames = 0;
	Capture->Settings.ZeroPadFrameNumbers = 0;
	Capture->Settings.FrameRate = FFrameRate(30, 1);
	Capture->Settings.bUseCustomFrameRate = false; // If true, set CustomFrameRate
	Capture->Settings.Resolution = FCaptureResolution(1920, 1080);
	Capture->Settings.bEnableTextureStreaming = false;
	Capture->Settings.bCinematicEngineScalability = false;
	Capture->Settings.bCinematicMode = false; // If true, set bAllowMovement, bAllowTurning, bShowPlayer, bShowHUD
	Capture->Settings.bUsePathTracer = false; // If true, set PathTracerSamplePerPixel

	// UAutomatedLevelSequenceCapture
	Capture->ShotName = "MyRender";
	Capture->bUseCustomStartFrame = false; // If true, set CustomStartFrame
	Capture->bUseCustomEndFrame = false; // If true, set CustomEndFrame
	Capture->WarmUpFrameCount = 0;
	Capture->DelayBeforeWarmUp = 0.0f;
	Capture->DelayBeforeShotWarmUp = 0.0f;
	Capture->DelayEveryFrame = 0.0f;
	Capture->bWriteEditDecisionList = false;
	Capture->bWriteFinalCutProXML = false;

	// ULevelSequenceBurnInOptions
	ULevelSequenceBurnInOptions* BurnIn = NewObject<ULevelSequenceBurnInOptions>();
	BurnIn->bUseBurnIn = true;
	Capture->BurnInOptions = BurnIn;

	// Start Render
	USequencerToolsFunctionLibrary::RenderMovie(Capture, FOnRenderMovieStopped());

	bOutSuccess = true;
	OutInfoMsg = FString::Printf(TEXT("Start Level Sequence Render Succeeded"));
}
PrivateDependencyModuleNames.AddRange
(
  new string[] 
  { 
    // Default Modules
    "Core", 
    "CoreUObject", 
    "Engine", 

    // Required Modules
    "LevelSequence",
    "SequencerScriptingEditor",
    "MovieSceneTools",
	"MovieSceneCapture",
	"AVIWriter",
  }
);