Adding a TimeWarp Curve to a shot track using pure C++

Our company is developing an in house Level sequence importer and as a part of the import process a ‘cinematic shot track’ is added to the Level sequence. We also need to add a TimeWarp curve to the shot track (The equivalent of going to the shot tracks section properties and changing the ‘Time Scale’ value).

Has anyone done this using C++ before and if so can you give tips on how to implement the code?

I’ve already tested code to generate and populate a timewarp track that gets added to the movie scene, but this has a global effect on all the tracks in the level sequence, what I’m after is just controlling the timing of a single cinematic shot track!

All help is most appreciated

[Attachment Removed]

Steps to Reproduce
Not an issue, just need help on how to implement a timewarp curve attached to a shot track using C++.

[Attachment Removed]

Hey there

Apologies for the delay, Epic was on summer break. If you want to add a timewarp curve to just a particular shot you could do something like the below (note this is rough untested code). I referenced a bit of FTimeWarpTrackEditor::HandleAddTimeWarpTrack flow.

//Assuming you have the shot section, get the current timewarp variant.
FMovieSceneTimeWarpVariant* Variant = ShotSection->GetTimeWarp();
 
if (!Variant)
{
    return;
}
 
//Add the modification.
const FScopedTransaction Transaction(LOCTEXT("AddTimeWarp", "Add Timewarp Curve"));
ShotSection->Modify();
 
UObject* OuterGet = ShotSection->GetTypedOuter<UMovieSceneSequence>();
 
//Create your timewarp curve variant
UMovieSceneTimeWarpCurve* Curve = NewObject<UMovieSceneTimeWarpCurve>(
    OuterGet ? OuterGet : ShotSection,   // outer
    NAME_None,
    RF_Transactional);
 
Curve->InitializeDefaults(ShotSection);
 
// Get it's channel.
FMovieSceneTimeWarpChannel& Channel = Curve->Channel;
 
 Channel.Reset();
 
TMovieSceneChannelData<FMovieSceneDoubleValue> Data = Channel.GetData();
 
// Build a key. Value = the source time this playhead position maps to.
auto MakeKey = [](double InValue, ERichCurveInterpMode Interp)
{
    FMovieSceneDoubleValue V(InValue);
    V.InterpMode = Interp;   // RCIM_Linear, RCIM_Cubic, RCIM_Constant...
    return V;
};
 
// Example: a speed ramp — start normal, ease into slow-mo, then back.
// (frames are FFrameNumber in the section's tick space)
Data.AddKey(StartFrame,  MakeKey(StartTimeValue,  RCIM_Cubic));
Data.AddKey(MidFrame,    MakeKey(MidTimeValue,    RCIM_Cubic));
Data.AddKey(EndFrame,    MakeKey(EndTimeValue,    RCIM_Cubic));
 
// Extrapolation outside the keyed range
Channel.PreInfinityExtrap  = RCCE_Constant;
Channel.PostInfinityExtrap = RCCE_Constant;
 
// Set the new curve
Variant->Set(Curve);
 
// Mark the change as complete.
ShotSection->MarkAsChanged();
// If you have a Sequencer ref:
Sequencer->NotifyMovieSceneDataChanged(EMovieSceneDataChangeType::MovieSceneStructureItemAdded);

Dustin

[Attachment Removed]