Sequencer自身の操作をするCustomTrackの作成について

お世話になっております。
SequencerのCustomTrackに、自身のSequencerの再生を一時停止させる機能を追加したいと思っております。

現在、EventTrackを改造用に複製し、ExecutionTokenのExecute関数内で停止させる処理を呼び出したいと思ったのですが問題が出てきてしまいました。
現在コードは以下のようにしております。

UMovieSceneSequencePlayer* MoviePlayer = StaticCast(&Player);
if (MoviePlayer && MoviePlayer->IsValidLowLevelFast())
{
	// ゲームプレイ中	
	MoviePlayer->Pause();
}
else
{
	// Preview中
	Player.SetPlaybackStatus(EMovieScenePlayerStatus::Stopped);
}

この条件分岐は、 IMovieScenePlayer::SetPlaybackStatus(EMovieScenePlayerStatus::Stopped) で停止するのはPreviewのときのみであり、ゲームプレイ中に再生したSequencerは停止しないため、判定によって処理を変更しております。

このとき、 IMovieSceneExecutionToken::Execute 関数の引数 IMovieScenePlayer がUObjectではないため、
停止させる UMovieSceneSequencePlayer::Pause 関数を呼び出すためには StaticCast の危険な型変換が必要になり、
Preview中だと不正なアクセスでクラッシュすることもあったため、このような処理だと不安があります。
(一時停止の機能はPreview、ゲームプレイ中どちらでも行いたいです)

また、Worldに置いたSequencerのBlueprintにEventを呼び出す形にすると
Previewで一時停止が行えなくなってしまい、さらに循環参照になりエラーがでてしまうため問題があります。

将来的には再生再開や、自身のSequcener再生時間のジャンプなどもTrack上から行いたいと考えておりますので、自身の UMovieSceneSequencePlayer のメンバ関数を呼べるような処理にしておきたいです。

上記のような処理で問題ないのでしょうか?他によりよい方法があるのでしょうか?
ご回答のほどよろしくお願いします。

お世話になっております。
本件返信にお時間を頂いてしまい申し訳ありません。

こちらでも同様の実装を行い検証を行ってみました。
まず挙動としましては、こちらPreviewではFSequencerから、
実行時にはMovieSceneSequencePlayerをthisとして呼び出されているようです。

◆Preview時

◆ゲーム実行時

IMovieScenePlayerにはSetPlaybackStatusがvirtual関数として定義されており、
FEventTrackExecutionTokenのExecuteから呼び出されていますが、
実装自体はFSequencerのみとなるため、FSequencerから呼び出されるPreview時では処理が走り、
MovieSceneSequencePlayerから呼び出されるゲーム実行時には、実装が空のため停止できていないようです。

.\release-4.20\Engine\Source\Runtime\MovieScene\Public\MovieSceneSequencePlayer.h

こちらの対応についてですが、
Interface経由でそれぞれの振る舞いを実装するのが安全かと思います。
以下例はHeaderに書いてしまっており少し強引ですが、
MovieSceneSequencePlayerのSetPlaybackStatusでPauseを行ったところ、
それぞれPause処理を実行できました。

上記箇所をご確認いただければと思います。
よろしくお願いいたします。

ご回答ありがとう御座います。

たしかにご提案いただいたエンジン改造による方法だとIMovieScenePlayerの型のまま動作させることができますので、危険なキャストがなくSequencerの停止は行えます。
しかし、

将来的には再生再開や、自身のSequcener再生時間のジャンプなども行いたいと考えておりますので、自身のUMovieSceneSequencePlayerのメンバ関数を呼べるような処理にしたいです。

といった点で、 SetPlaybackPosition 関数などが呼べないという問題が出てきてしまいます。

IMovieScenePlayer などで再生位置をジャンプする方法が他にあれば異なる関数を呼ぶことで対処できるのですが、みたところIMovieScenePlayerを継承した ISequencer::SetLocalTime 関数ですので、同様の危険なキャストが必要な問題がありそうです。

お世話になっております。

その他の処理に関しましてもCastを使わない場合は、
Interfaceを経由にそれぞれの振る舞いを実装することになるかと思います。

例としましてSequcener再生時間の移動であれば、IMovieScenePlayerで以下のような宣言を行い、
それぞれのクラス内でアクセスできる関数を用いて実装を行うことで実現できるかと思います。
.\release-4.20\Engine\Source\Runtime\MovieScene\Public\IMovieScenePlayer.h
SetPlaybackPositionをIMovieScenePlayerで宣言

MovieSceneSequencePlayerではSetPlaybackPositionが実装済みなので使用可能となっており、
FSequencerの方には存在しないためFSequencerのみSetPlaybackPositionを実装します。

IMovieSceneExecutionTokenの方からSetPlaybackPositionを呼び出すことで、
例では0.5秒に戻るような処理となっています。

257737-seqtest3.gif

FSequencer内の移動処理については、
Loopの処理を探していただくと参考になるかと思います。

こちらの方法をご検討いただけますと幸いです。
よろしくお願いいたします。

お世話になっております。
詳細な実装を書いていただきありがとう御座います。

やはり危険なCastをしない場合にはエンジン改造をする必要があるのですね。
またこちらでも調査したところ、FSequencerが追加実装を行わないと特定の位置にジャンプすることができず、
関数が実装されていてもFSequencerクラス自体がPrivateで参照できないため、改造必須なこともわかりました。

さっそくいただいたコードで実験したところ、FSequencer動作時(Simulation時)は問題がありませんでした。ありがとう御座います。
しかし、 UMovieSceneSequencePlayer::SetPlaybackPosition 関数はVer4.20でDEPRECATEDになっておりましたので、代わりに PlayToSecond 関数を使用したのですが、
うまく時間がジャンプしなかったため、 JumpToSecond 関数を使用したところ FSequencer::SetPlaybackPosition 関数に渡す引数と同値で同じ位置にジャンプするように対応できました。
また、キャスト後の判定部分で IsValidLowLevelFast 関数ではなく IsValidLowLevel 関数を呼んでいると現状クラッシュが起こっておりませんので、
可能な処理はCastからの呼び出しで動作の様子を見ていきます。

再生時間のジャンプなども問題が起こらないか様子をみていき、問題が起こった際にはさらにインターフェイスとなる関数を追加するといった、必要があれば最小限にエンジン改造をする方針でいきたいと思います。

ありがとう御座いました。