シーケンサーエディタでアニメーションセクションのAutoSizeが動作しないケースがある

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

<br/>

シーケンサーエディタで、アニメーションセクションを右クリックして表示されるコンテキストメニューから実行できる “Edit > Auto Size” について、アニメーションセクションを、アニメーションセクションに設定されているアニメーションの長さより後ろのフレームに移動させると、“Auto Size” が動作しません。

<br/>

このとき、以下のensureでひっかかっていました。

// UE\Engine\Source\Runtime\MovieScene\Public\MovieSceneSection.h
// L.333
		const bool bInvariants = ensure(
			NewRange.GetLowerBound().IsOpen() || NewRange.GetUpperBound().IsOpen()
			|| NewRange.GetLowerBoundValue() <= NewRange.GetUpperBoundValue()
			);

<br/>

また、アニメーションセクションを、アニメーションの長さと同じフレームをまたいで配置して"Auto Size"を実行すると、アニメーションがループするフレームではなく、またいだフレームにサイズが調整されます。

<br/>

ご確認よろしくお願いいたします。

[Attachment Removed]

再現手順

  1. LevelSequenceを新規作成して開く
  2. Characterを配置する
  3. Characterに、アニメーションが用意されている任意のメッシュを設定する
  4. 0フレーム目に任意のアニメーションを設定する
  5. アニメーションセクションの長さを短くする(ここで Auto Size を実行すると元の長さに戻る)
  6. アニメーションセクションを、アニメーションの長さより大きく後ろにずらす
  7. アニメーションセクションの Auto Size を実行する
  8. アニメーションセクションの長さが元に戻らないことを確認する
    [Attachment Removed]

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

ご報告ありがとうございます。

また、詳細な再現手順をありがとうございました。確かにensureがトリガーされることを確認しました。

本件は不具合としてバグトラッカーに起票いたしました。Public Issueとして承認後、下記のURLから修正状況を追跡いただける予定です。

https://issues.unrealengine.com/issue/UE-381333

取り急ぎの回避策として暫定パッチを準備しましたので、お試しいただければと思います。

Engine\Source\Runtime\MovieSceneTracks\Private\Sections\MovieSceneSkeletalAnimationSection.cpp:350付近

FFrameTime InnerStartTime = Params.StartFrameOffset + Params.FirstLoopStartFrameOffset;
	FFrameTime InnerEndTime = IFrameNumber - Params.EndFrameOffset;
 
+	const TOptional<FFrameTime> OuterStartTimeOpt = InnerToOuterTransform.TryTransformTime(InnerStartTime);
+	const TOptional<FFrameTime> OuterEndTimeOpt   = InnerToOuterTransform.TryTransformTime(InnerEndTime);
+
+	FFrameNumber OuterLengthFrames;
+	if (OuterStartTimeOpt.IsSet() && OuterEndTimeOpt.IsSet())
+	{
+		OuterLengthFrames = (OuterEndTimeOpt.GetValue() - OuterStartTimeOpt.GetValue()).FrameNumber;
+	}
+	else
+	{
+		const double InnerLengthTicks = (InnerEndTime - InnerStartTime).AsDecimal();
+		double PlayRateValue = (Params.PlayRate.GetType() == EMovieSceneTimeWarpType::FixedPlayRate)
+			? FMath::Abs(static_cast<double>(Params.PlayRate.AsFixedPlayRateFloat()))
+			: 1.0;
+
+		if (UAnimSequenceBase* AnimSeq = Params.Animation)
+		{
+			PlayRateValue *= FMath::Abs(static_cast<double>(AnimSeq->RateScale));
+		}
+
+		if (PlayRateValue <= UE_SMALL_NUMBER)
+		{
+			PlayRateValue = 1.0;
+		}
+		OuterLengthFrames = FFrameTime::FromDecimal(InnerLengthTicks / PlayRateValue).FrameNumber;
+	}
+	return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + OuterLengthFrames);
-	const FFrameTime OuterStartTime = InnerToOuterTransform.TryTransformTime(InnerStartTime).Get(InnerStartTime);
-	const FFrameTime OuterEndTime = InnerToOuterTransform.TryTransformTime(InnerEndTime).Get(InnerEndTime);
-
-	return TRange<FFrameNumber>(GetInclusiveStartFrame(), GetInclusiveStartFrame() + (OuterEndTime - OuterStartTime).FrameNumber);

ただし、あくまで暫定の修正となるため、大変恐縮ながら現状では Time Warp カーブなどにうまく対応できておりません。こうした制限で実務上の問題が生じる場合はご一報ください。

以上、取り急ぎご返信申し上げます。

[Attachment Removed]

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

ご提示いただいたコードで修正されることを確認いたしました。

この状態でも作業に問題はなさそうです。

また何かありましたらよろしくお願いいたします。

本件はクローズで問題ございません。

ご対応ありがとうございました。

[Attachment Removed]

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

パッチのご確認ありがとうございました!

​作業に支障ない状況になったと聞き、安心いたしました。

それでは本件は対応済みとしてCloseさせていただきます。

以上、よろしくお願いいたします。​

[Attachment Removed]