UE5.8よりアニメーションシーケンスの先頭付近に設定した AnimNotify が発火しない場合があります

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

UE5.8より、アニメーションシーケンスの先頭付近に設定した AnimNotify が発火しない場合があります。

以下の EPS に報告があり、同様の症状だと考えております。

[Content removed]

内容から不具合回避のために、‘a.EnableQueuedAnimEventsOnServer 0’ の設定を検討しております。

上記設定により、PIE上で不具合が解消されているのは確認できました。

EnableQueuedAnimEventsOnServer を検索すると、UE5.1辺りでサーバーサイドの Notify が発火しない問題の対処のために追加されたフラグのようで、‘a.EnableQueuedAnimEventsOnServer 0’ にすることで別の影響がないかご教示いただければと思います。

Listen Server は使用しておりますが、Dedicated Server は未使用の環境でございます。

また、他によい解決方法がありましたらご教示ください。

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

[Attachment Removed]

Hi, no unfortunately I wouldn’t recommend setting ‘a.EnableQueuedAnimEventsOnServer 0’ if you are running Listen server builds, as that would likely reinstate the original bug that we hit back in 5.1 with notifies not being triggered in Listen servers. The subsequent issues have all been related to the original fix for that issue.

I’ve exposed the ticket for that issue to the JIRA tracker so you can see more details here. We are still working on a potential fix for this, with the aim of including it in one of the 5.8 hotfix releases. You can track the status of the issue here, and I will post a fix once we have one on the other EPS thread you referenced.

translated using Google Translate:

こんにちは。残念ながら、Listenサーバーのビルドを運用されている場合、『a.EnableQueuedAnimEventsOnServer 0』の設定は推奨いたしません。これを行うと、バージョン5.1で発生していた「Listenサーバー上でアニメーション通知(Notify)がトリガーされない」という不具合が再発する可能性が高いためです。その後の関連する問題はすべて、この不具合に対する当初の修正に起因するものです。

当該不具合に関するチケットをJIRAトラッカー上で公開しましたので、詳細はこちらでご確認いただけます。現在、5.8のホットフィックス・リリースへの組み込みを目指して修正案の検討を進めているところです。不具合の状況はこちらで追跡可能です。修正が完了次第、ご参照いただいたEPSスレッドにてお知らせいたします。

[Attachment Removed]

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

a.EnableQueuedAnimEventsOnServer 0 の設定は行わず、引き続きチケットにて問題の状況を追跡してまいります。

状況によっては、ワークアラウンドの方法などをご相談させていただく可能性があります。

その際は、よろしくお願いいたします。

[Attachment Removed]

Sure, that sounds good. A timescale for the fix is hard to say for certain as it depends on the complexity of the changes required, and the availability of the dev team. But for now at least, we’re targeting a fix in the 5.8.4 release.

Are you happy for me to close out this thread, or do you want to discuss possible workarounds?

---

承知いたしました。修正にかかる期間については、必要な変更の複雑さや開発チームの状況次第となるため、現時点では確実なことは申し上げられません。ただ、少なくとも現段階では、バージョン5.8.4での修正を目標としています。

このスレッドをクローズしてもよろしいでしょうか?それとも、回避策について話し合いたいとお考えでしょうか?

[Attachment Removed]

Thank you for the information regarding the target version for the fix.

As we have some concerns about the release timing of UE5.8.4, we would like to consider a workaround in the meantime.

(1)

We are considering reverting the timing at which Notify dispatch is executed in CharacterMovementComponent.cpp

back to the behavior of UCharacterMovementComponent::MoveAutonomous in UE5.7.4.

This would reintroduce the UE-308913 issue, but fortunately we do not use a dedicated server, and we did not observe that issue in UE5.7.4.

(2)

As an alternative, we are also considering replacing the critical Notifies with Branching Points.

This would be a fallback option in case approach (1) turns out to be difficult due to requiring too many changes to the Engine. Since it would require inspecting a large amount of data and may also have some performance impact, we would prefer to pursue approach (1) first.

Regarding approach (1), could you please confirm whether this kind of modification is appropriate?

Also, if there is any better workaround, we would greatly appreciate your guidance.

Note: We tried the following code.

CharacterMovementComponent.cpp
 
■
void UCharacterMovementComponent::MoveAutonomous - Restore the dispatch processing
(around Line ~10714)
 
	// If not playing root motion, tick animations after physics. We do this here to keep events, notifies, states and transitions in sync with client updates.
	if (CharacterOwner && !CharacterOwner->bClientUpdating && !CharacterOwner->IsPlayingRootMotion() && CharacterOwner->GetMesh())
	{
		if (!bWasPlayingRootMotion) // If we were playing root motion before PerformMovement but aren't anymore, we're on the last frame of anim root motion and have already ticked character
		{
			TickCharacterPose(DeltaTime);
		}
		// TODO: SaveBaseLocation() in case tick moves us?
 
		USkeletalMeshComponent* OwnerMesh = CharacterOwner->GetMesh();
		check(OwnerMesh != nullptr)
#if 1 // [START : Revert AnimNotify dispatch timing to UE5.7.4 behavior]
		if (CharacterMovementCVars::EnableQueuedAnimEventsOnServer)
		{
			if (UAnimInstance* AnimInstance = OwnerMesh->GetAnimInstance())
			{
				if (OwnerMesh->VisibilityBasedAnimTickOption <= EVisibilityBasedAnimTickOption::AlwaysTickPose && AnimInstance->NeedsUpdate())
				{
					// If we are doing a full graph update on the server but its doing a parallel update,
					// trigger events right away since these are notifies queued from the montage update, and we could be receiving multiple ServerMoves per frame.
					OwnerMesh->ConditionallyDispatchQueuedAnimEvents();
 
					// We need to manually clear the anim notify queue (since normally its only is cleared in PreUpdateAnimation()) otherwise if animation ticks, the notifies queued from the ServerMove would fire twice.
					AnimInstance->ClearQueuedAnimEvents(false);
 
					// When animation ticks, we want its queued events to be triggered.
					OwnerMesh->AllowQueuedAnimEventsNextDispatch();
				}
			}
		}
		else
#else // [END : Revert AnimNotify dispatch timing to UE5.7.4 behavior]
		// Fallback to old behaviour if needed. Otherwise, event are dispatched in TickCharacterPose().
		if (!CharacterMovementCVars::EnableQueuedAnimEventsOnServer)
#endif
		{
			// Revert back to old behavior if wanted/needed.
			if (OwnerMesh->ShouldOnlyTickMontages(DeltaTime) || OwnerMesh->ShouldOnlyTickMontagesAndRefreshBones(DeltaTime))
 
 
■
TickCharacterPose() - Disabled the dispatch processing added in 5.8
(around Line ~12107)
 
#if 0 // [START : Revert AnimNotify dispatch timing to UE5.7.4 behavior]
		// We need to dispatch any queued events, since these can affect the next move request, after we ticked the character pose.
		if (CharacterMovementCVars::EnableQueuedAnimEventsOnServer)
		{
			UAnimInstance* AnimInstance = CharacterMesh->GetAnimInstance();
			UAnimInstance* PostProcessAnimInstance = CharacterMesh->GetPostProcessInstance();
			
			if (AnimInstance || PostProcessAnimInstance)
			{
				const bool bIsAnimGraphUpdateEnabled = CharacterMesh->VisibilityBasedAnimTickOption <= EVisibilityBasedAnimTickOption::AlwaysTickPose;
				const bool bIsMainAnimGraphUpdatePending = AnimInstance ? AnimInstance->NeedsUpdate() : false;
				const bool bIsPostProcessAnimGraphUpdatePending =  PostProcessAnimInstance ? PostProcessAnimInstance->NeedsUpdate() : false;
				const bool bIsAnimGraphUpdatePending = bIsMainAnimGraphUpdatePending || bIsPostProcessAnimGraphUpdatePending;
				
				if (bIsAnimGraphUpdateEnabled && bIsAnimGraphUpdatePending)
				{
					// If we are doing a full graph update on the server but its doing a parallel update,
					// trigger events right away since these are notifies queued from the montage update, and we could be receiving multiple ServerMoves per frame.
					CharacterMesh->ConditionallyDispatchQueuedAnimEvents();
 
					// We need to manually clear the anim notify queue (since normally its only is cleared in PreUpdateAnimation()) otherwise if animation ticks, the notifies queued from the ServerMove would fire twice.
					CharacterMesh->ForEachAnimInstance([](UAnimInstance* InAnimInstance)
					{
						check(InAnimInstance);
						InAnimInstance->ClearQueuedAnimEvents(false);
					});
 
					// When animation ticks, we want its queued events to be triggered.
					CharacterMesh->AllowQueuedAnimEventsNextDispatch();
				}
			}
		}
#endif // [END : Revert AnimNotify dispatch timing to UE5.7.4 behavior]

Thank you very much for your support.

---

修正の対象バージョンの情報など、ありがとうございます。

UE5.8.4 の対応時期などに不安があり、ワークアラウンドを検討したいと思っております。

(1)

CharacterMovementComponent.cpp の Notify の Dispatch 実行タイミングを、

UE5.7.4 の UCharacterMovementComponent::MoveAutonomous に戻すことにより対応できないか考えております。

UE-308913 の不具合は戻ってしまいますが、幸い Dedicated Server は未使用で、UE5.7.4 では当該不具合を認識しておりませんでした。

(2)

もう一つの案として、重要な Notify を Branching Point に置き換えることも検討しています。

こちらは (1) の対応で Engine への変更が多くなり対応が難しそうな場合の代替案です。

多くのデータの検査が必要で、パフォーマンスへの影響も多少ありそうなため、まずは (1) を検討したいと考えております。

(1) の対応に関して、このような修正が適切か、ご確認いただけませんでしょうか?

また、他によいワークアラウンドがありましたら、ご教示いただければと思います。

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

[Attachment Removed]

Hi, yes, if you’re running a listen server, then you could revert the changes in 5.8 to avoid the issue while still keeping ‘a.EnableQueuedAnimEventsOnServer’ enabled. Be aware, however, that the CL that those changes originated from is larger than just the modifications to CharacterMovementComponent.cpp. You can see the full set of changes in CL 47265321.

Let me know if you run into any problems or have further questions.

----

はい、リッスンサーバーを運用されている場合、`a.EnableQueuedAnimEventsOnServer` を有効にしたまま問題の発生を回避するには、バージョン5.8での変更を元に戻す(リバートする)という方法があります。ただし、その変更が含まれるCL(チェンジリスト)には、`CharacterMovementComponent.cpp` への修正以​​外の変更も含まれている点にご注意ください。変更の全容は、CL 47265321 で確認できます。

何か問題が生じたり、さらに質問があったりした場合はお知らせください。

[Attachment Removed]