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!
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);