いつもお世話になっております。
シーケンサーで SetPlaybackRange を使って区間を指定し、PlayLooping でループ再生を行った場合、
指定区間外であるにもかかわらずシーケンサーの先頭付近のイベントが評価されてしまいます。
具体的には、、、
・5秒のレベルシーケンスを用意
・SetPlaybackRange(2,4) で2秒~4秒の再生区間を指定
・PlayLooping でループ再生を開始
→0秒付近に配置したイベントが評価されてしまいます。
SetPlaybackRangeを指定した場合、GetPlaybackPositionで取得できるシーケンサーの再生位置は再生区間内のローカル位置と理解しています。(上記の場合、2秒~4秒の区間で GetPlaybackPositionは 0→2 の範囲)
ループで折り返した瞬間、本来は2秒のところから評価されるべきかと思いますが、0秒からイベント評価されていないでしょうか?
ご確認お願いします。
以上です。
お世話になっております。本件解決までお時間を頂いてしまい申し訳ありません。
こちらの件に関しまして検証を行ってみましたところ、ご報告の現象を再現いたしました。
実装を確認したところ、ループ時に行っているイベント評価のための
範囲初期化に問題があり今回の現象が発生しているようです。
取り急ぎ問題の特定と暫定の修正を行いましたので本文以下に記述させていただきます。
コードに関しましては公式にマージしたものではないので、
保守保証などはできませんが、参考にしていただけますと幸いです。
こちらの修正で、ループを行った場合にイベントの範囲が正常になることを確認しています。
注意点としまして、ループした戻った時、また戻った位置とちょうど同じ時間に、
イベントがあった場合にイベントが発生しない問題を確認しています。
こちら整合性を保ちつつの修正が難しく、
微小な数を引く、といった対応で現状回避することができます。
また以下にバグとしてデータベースに登録させていただきました。
引き続き進展などがありましたらご連絡させていただきます。
UE-61468 - Event is incorrect when loop playback on Sequencer with SetPlaybackRange
お手数おかけしますが、よろしくお願いいたします。
\release-4.19\Engine\Source\Runtime\MovieScene\Public\Evaluation\MovieScenePlayback.h
/** Helper class designed to abstract the complexity of calculating evaluation ranges for previous times and fixed time intervals */
struct MOVIESCENE_API FMovieScenePlaybackPosition
{
/**
* Reset this position to the specified time.
* @note Future calls to 'PlayTo' will include this time in its resulting evaluation range
*/
void Reset(float StartPos);
void ForceSetPreviousPlayEvalPosition(float StartPos); //追加
\release-4.19\Engine\Source\Runtime\MovieScene\Private\Evaluation\MovieScenePlayback.cpp
void FMovieScenePlaybackPosition::Reset(float StartPos)
{
PreviousPosition = StartPos;
PreviousPlayEvalPosition.Reset();
LastRange.Reset();
}
// ここから
void FMovieScenePlaybackPosition::ForceSetPreviousPlayEvalPosition(float StartPos)
{
PreviousPlayEvalPosition = StartPos;
}
// ここまで
FMovieSceneEvaluationRange FMovieScenePlaybackPosition::JumpTo(float NewPosition, TOptional FixedInterval)
\release-4.19\Engine\Source\Runtime\MovieScene\Private\MovieSceneSequencePlayer.cpp
// loop playback
if (PlaybackSettings.LoopCount < 0 || CurrentNumLoops < PlaybackSettings.LoopCount)
{
++CurrentNumLoops;
const float Overplay = FMath::Fmod(NewPosition, Length);
TimeCursorPosition = Overplay < 0 ? Length + Overplay : Overplay;
PlayPosition.Reset(Overplay < 0 ? Length : 0.f);
PlayPosition.ForceSetPreviousPlayEvalPosition(StartTime); // 追加
FMovieSceneEvaluationRange Range = PlayPosition.PlayTo(GetSequencePosition(), FixedFrameInterval);
if (SpawnRegister.IsValid())
{
SpawnRegister->ForgetExternallyOwnedSpawnedObjects(State, *this);
}
ご回答ありがとうございます。
書いていただいた方法で、ループ時にループ区間外の冒頭のイベントがコールされないことを確認できました。
ありがとうございます。
ただ、本件の修正が原因かどうか図りかねていますが、別のエラーが良く発生するようになってしまいました。
link text
クラッシュログを添付いたします。
(元々のこちらのUE4の使い方に問題があれば申し訳ありません)
こちら、何か原因として考えられることはありますでしょうか?
また、近日中にUE4.20 へのアップデートを予定しています。
今回ご説明頂いた修正方法は、そのまま4.20でも利用可能でしょうか?
お手数おかけしますが、ご確認のほど、よろしくお願いします。
以上です。
申し訳ありません。
クラッシュについては、ループ範囲設定時に合わせて行っていた
JumpToPosition
による再生位置設定を
SetPlaybackPosition
に変更してみたところ、発生しなくなりました。
エンジンのソースコードの修正とは無関係でした。申し訳ありませんでした。
UE4.20へのアップデート時の対応についてはご確認いただけるとありがたいです。
以上
よろしくお願いします。
お世話になっております。返信が遅くなり申し訳ありません。
エラーの件に関しましてはSetPlaybackPositionで発生しなくなったとのことで安心いたしました。
こちらで一旦回避していただければと思います。
JumpToPositionで発生する問題と4.20での対応に関しましては、週明けに検証を行い返信させていただきたいと考えております。
また恐縮ですが本件の修正は現在4.21の予定となっております。
お手数おかけしますが、よろしくお願いいたします。