Swap actor binding on sequence c++

I am attempting to create an actor that takes a level sequence as a parameter. This sequence needs to dynamically use AI characters based on dynamic factors.

I have found the “SetBinding” function on the sequence player, which takes the “FMovieSceneObjectBindingID”, and the new actor/s to bind. I am unable to find any way of finding/creating the FMovieSceneObjectBindingID though. Theres no function within the engine as far as I can tell which returns this value, or a function attached to ULevelSequence, ULevelSequencePlayer or any other relevant object.

Is there a way to find the Binding ID from sequence that I am missing? The blueprint nodes are helpful, but once again this logic does not seem to be implemented anywhere in C++ and I’d like to encode this functionality in my base class so I don’t need to expose my level designers to it.

The blueprint nodes are implemented in C++ so you can reference them to see how it is done. The “Get Binding” node is implemented in MovieSceneObjectBindingIDPicker.cpp, as FMovieSceneObjectBindingIDPicker.

You may also want to try looking at the source code for these sets of nodes, which are part of the Sequencer Scripting plugin.

FSequencerBindingProxy UMovieSceneSequenceExtensions::FindBindingByName(UMovieSceneSequence* Sequence, FString Name)

FMovieSceneObjectBindingID UMovieSceneSequenceExtensions::MakeBindingID(UMovieSceneSequence* MasterSequence, const FSequencerBindingProxy& InBinding, EMovieSceneObjectBindingSpace Space)

Hi sir. Thanks for your answer and it really helps. But currently I’m encountering an “unknown symbol” problem about UMovieSceneSequenceExtensions. I have added the “SequencerScripting” module and the “MovieScene” module into the Build.cs file, like this:
PublicDependencyModuleNames.AddRange(new string[]
{ “Core”, “CoreUObject”, “Engine”, “InputCore”, “EnhancedInput”, “LevelSequence”, “SequencerScripting”, “MovieScene” });

and added headers into my cpp file, like this:
#include “ExtensionLibraries/MovieSceneSequenceExtensions.h”

Could you please help me figure out why this “unknown symbol UMovieSceneSequenceExtensions::GetBindingID” happens?

Thank you in advance.

@sequencermatt

Hi, could you please help me, thanks!

UMovieSceneSequenceExtensions methods are not exported. They don’t have the PLUGIN_API macro in the class, so you can’t link to them. Someone on discord said you can copy the plugin into your own project and add your own API macro and rebuild, but seems like a bit of work.

Here’s what I got:

#include "LevelSequencePlayer.h"
#include "MovieSceneSequencePlaybackSettings.h"
#include "DefaultLevelSequenceInstanceData.h"
#include "LevelSequenceActor.h"

void UMyAnimInstance::StartSequence_Implementation()
{
    FMovieSceneSequencePlaybackSettings Settings;
    ALevelSequenceActor *SequenceActor = nullptr;
    ULevelSequencePlayer* player = ULevelSequencePlayer::CreateLevelSequencePlayer(this, this->MySequence, Settings, SequenceActor);
    check(player);
    check(SequenceActor);

    SequenceActor->bOverrideInstanceData = 1;
    UDefaultLevelSequenceInstanceData* InstanceData = Cast<UDefaultLevelSequenceInstanceData>(SequenceActor->DefaultInstanceData.Get());
    InstanceData->TransformOrigin = this->GetOwningActor()->GetActorTransform();

    UMovieScene* MovieScene = this->MySequence->GetMovieScene();
    check(MovieScene);
    const FMovieSceneBinding* Binding = Algo::FindBy(MovieScene->GetBindings(), FString("SequencerActor"), &FMovieSceneBinding::GetName);
    check(Binding);

    EMovieSceneObjectBindingSpace Space = EMovieSceneObjectBindingSpace::Root;

    FMovieSceneObjectBindingID BindingID = UE::MovieScene::FRelativeObjectBindingID(Binding->GetObjectGuid());
    // Not sure about this
    if (Space == EMovieSceneObjectBindingSpace::Root)
    {
        BindingID.ReinterpretAsFixed();
    }

    SequenceActor->AddBinding(BindingID, this->GetOwningActor());
    player->Play();

    // Save actor and player in properties
    this->SequencerActor = SequenceActor;
    this->SequencerPlayer = player;
}

1 Like

Thanks so much!

You can also use this API: LevelSequenceActor->AddBindingByTag(FName(TEXT("Your Tag")), TargetActor); and config a tag for your track in the LevelSequence Editor.