How to add keys to Sequencer Track using C++

I wanted to automate adding some float keys for my actor in the sequencer. How do I go about this?

void TestBlueprintFunctionLibrary::SetFloatKey(ULevelSequence* LevelSequence, UObject* Object, float Value, float Time)
{
	float Fps = DisplayRate.AsDecimal();
	FFrameNumber Frame;		
	Frame.Value = Fps * Time;
	UMovieSceneTrack* MovieSceneTrack = LevelSequence->MovieScene->FindTrack(UMovieSceneFloatTrack::StaticClass(), Guid);
	TArray <UMovieSceneSection*> MovieSceneSections = MovieSceneTrack->GetAllSections();
	UMovieSceneFloatSection* FloatSection = Cast<UMovieSceneFloatSection>(MovieSceneSections[0]);
	FMovieSceneFloatChannel FloatChannel = FloatSection->GetChannel();
	TArray <FFrameNumber> Frames;
	TArray <FMovieSceneFloatValue> Values;
	Frames.Add(Frame);
	Values.Add(FMovieSceneFloatValue(Value));		
	FloatChannel.AddKeys(Frames, Values);
}

When I try this nothing gets added in.

You can check F3DTransformTrackEditor::ImportAnimSequenceTransforms method.
This methods create some root motion keys for the sequence actor

this method can be launched from here:

Hope this helps

Solution:

#include "Editor/MovieSceneTools/Public/KeyframeTrackEditor.h"
#include "LevelSequence.h"
#include "MovieScene.h"
#include "MovieSceneFloatSection.h"
#include "MovieSceneFloatTrack.h"

bool UMyBlueprintFunctionLibrary::SetFloatKey(ULevelSequence* LevelSequence, UObject* Object, float Value, float Time, const FName Name)
{
#if WITH_EDITOR
	if (LevelSequence && Object)
	{
		FGuid Guid;
		if (FindBinding(LevelSequence, Object, Guid))
		{
			UMovieSceneFloatTrack* MovieSceneTrack = LevelSequence->MovieScene->FindTrack<UMovieSceneFloatTrack>(Guid, Name);

			if (MovieSceneTrack)
			{
				TArray <UMovieSceneSection*> MovieSceneSections = MovieSceneTrack->GetAllSections();
				if (MovieSceneSections.Num())
				{
					UMovieSceneFloatSection * FloatSection = nullptr;
					FloatSection = CastChecked<UMovieSceneFloatSection>(MovieSceneSections[0]);
					if (FloatSection)
					{
						if (FloatSection->TryModify(true))
						{
							TArrayView <FMovieSceneFloatChannel*> Channels = FloatSection->GetChannelProxy().GetChannels<FMovieSceneFloatChannel>();
							FFrameNumber Frame;
							Frame.Value = Time * 1000;
							Frame++;
							Channels[0]->GetData().UpdateOrAddKey(Frame, FMovieSceneFloatValue(Value));
						}
						return true;
					}
				}
			}
		}
	}
#endif	
	return false;
}

bool UMyBlueprintFunctionLibrary::FindBinding(ULevelSequence *LevelSequence, UObject *Object, FGuid & Guid)
{
	if (LevelSequence && Object)
	{
		for (auto b : LevelSequence->MovieScene->GetBindings())
		{
			FGuid ObjectGuid = b.GetObjectGuid();
			if (ObjectGuid.IsValid())
			{
				TArray<UObject*, TInlineAllocator<1>> Objects;
				LevelSequence->LocateBoundObjects(ObjectGuid, GWorld, Objects);
				if (Objects.Num())
				{
					if (Object == Objects[0])
					{
						Guid = ObjectGuid;
						return true;
					}
				}
			}
		}
	}
	return false;
}
2 Likes