Download

Sequencer - Get value at time

Hi,

I am trying to recreate a 3dsMax-style Ease Curve for the Unreal Sequencer. That means, I want to get the transform value of an object (like the camera) at a certain time in the sequencer and set this value to the object at the current time. For this I created a simple float parameter curve, which controls the time remapping, like so:

But as far as I know there is actually no Blueprint node that can get the value of a track at another time. Is there a node that can do that or some kind of workaround? Also, is there a blueprint that returns the current timeslider time? (I could just use a manual “time” float track for that I guess)

The Time Dilation track in the sequencer is close to what I want. But it works based on speed rather than frametime, which changes my total frame length (I want to render it with consistent length).

I also tried to create a new node in C++, but with no success as I am new to it.
I found a forum entry with some code I adjusted, but there is no “GetFloatCurve()” function for the RichCurve as described:
https://forums.unrealengine.com/deve…ck-section-how


error C2039: 'GetFloatCurve': is not a member of 'UMovieSceneFloatSection'

Any ideas for a Blueprint or C++ solution?

Maybe they changed it. UMoveSceneFloatSection has a GetChannel() member and in the channel (FMovieSceneFloatChannel) has Evaluate(FFrameTime InTime, float& OutValue).

If you have the float section, you maybe could evaluate it with



const FMovieSceneFloatChannel& Channel = FloatSection->GetChannel();
int32 FrameNumber = 0; // the frame to evaluate the curve at

float Value;
bool Success = Channel.Evaluate(FFrameTime(FrameNumber), Value);
if (Success)
{
// successfully evaluated. Value has the curve value.
}


Thanks for your reply!

I implemented those lines and it builds successfully. Evaluate seems to be exactly what I need!
When I put the node in a Blueprint though, Unreal crashes when I compile it:


Assertion failed: (Index >= 0) & (Index < ArrayNum) [File:D:\Build\++UE4+Licensee\Sync\Engine\Source\Runtime\Core\Public\Containers/Array.h] [Line: 674] Array index out of bounds: 0 from an array of size -109292494

Is Evaluate using and internal array that is faulty in some way? When I remove the Evaluate-line the crash doesn’t occur, so I think the rest of the script is OK.

If you compile it or if you run it? If it’s crashing when compiling the blueprint, it looks like a hot reload problem. Try to close the editor, build it in VS, then start the editor and try again. Always do it this way or use live-coding. If it’s not working, try it with a new blueprint. Hot reload is deprecated and can cause much problems.

If this is not the problem, then sorry, I don’t know. I just followed the chain from FMovieSceneChannel and searched for a function that seems to evaluate a curve. It’s worth a try, but I have no deeper understanding of the sequencer code.

I forgot to mention that the node will be triggered in the Construction Script. This way it can update with changing the Sequencer timeslider. That’s why it crashed when compiling the blueprint - it got triggered immediately.
As a test I hooked it up to an Event Begin Play. It compiled successfully, but Unreal crashes in the same way when I hit Play.

I am wondering why this is so hard to implement and now it seems it’s not possible at all. In After Effects there’s a direct “valueAtTime(time)” expression or in Nuke you just type “variablename(time)”. I easily got this system working in both programs that way.

This is my current code that makes Unreal crash

Header


 UFUNCTION(BlueprintPure, Meta = (DisplayName = "Get Value at Time"))
  static TArray<float> ValueAtTime(
    const UMovieSceneSequence* Seq,
    const FFrameTime Time,
    TSubclassOf<UMovieSceneTrack> TrackClass
);

Base


TArray<float> UMM_Library::ValueAtTime(const UMovieSceneSequence* Seq, const FFrameTime Time, TSubclassOf<UMovieSceneTrack> TrackClass) {
  TArray<float> curves;
  TArray<UMovieSceneTrack*> tracks;

  TArray<UMovieSceneSection*> Sections = Seq->GetMovieScene()->GetAllSections();
  for (UMovieSceneSection* Section : Sections)
  {
    UMovieSceneFloatSection* FloatSection = (UMovieSceneFloatSection*)Section;
    if (FloatSection)
    {
      const FMovieSceneFloatChannel& Channel = FloatSection->GetChannel();
      float Value;
      bool Success = Channel.Evaluate(Time, Value);
      if (Success) {
        curves.Add(Value);
      }
    }
  }
  return curves;
}

(TrackClass is for different track classes to choose, but first I try to get it to work for float tracks)

Hi! Quick note to this discussion, in case you use this you’ll probably need to include the “MovieSceneTracks” module to your Build.cs dependencies!!