レベルにSpawnしたCameraActorが数フレーム経過すると突然原点の座標に設定されてしまう

Tickで毎フレーム固定の位置に設定しており、固定値にカメラを配置しているが、スポーン後数フレーム経過すると突然カメラのLocationが原点になってしまった。

<br/>

原因がわからないため、この現象を防ぐために見直す必要がある設定項目を教えていただけないでしょうか

[Attachment Removed]

再現手順
【手順】​

1.レベルを起動

2.cameraactorをspawn

SpawnActor<ACameraActor>

[Attachment Removed]

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

Tickで毎フレーム、絶えず特定の位置を指定し続けているにも関わらず、数フレーム経過後に原点に​戻る症状を見せていることから、理屈の上ではネットワークレプリケーションが最も疑わしいと考えておりますが、お心当たりはございますでしょうか?

OnRep_ReplicatedMovement() から呼び出される PostNetReceiveLocationAndRotation()​ 関数の中で、サーバー側の座標と姿勢に同期するために、 ​SetActorLocationAndRotation() が呼び出されます。ここで、サーバー側のアクタが動いておらず、受信した座標が (0, 0, 0) になっていれば、原点に戻されるということが起こりえます。

レプリケーションが始まるまで数フレームの時差があるはずですので、これが「原点戻しが発生するのが、“スポーンしてから数フレーム後”」という症状​と合致するのではないかとも考えております。

試しに、​スポーンしたカメラアクタの SetReplicateMovement(false) を呼び出して、レプリケーションを切ってテストしてみていただけないでしょうか。もしこのフラグがほかのコードからコントロールされている可能性があるのであれば、毎Tick座標を書き込む際に一緒に呼び出すのも手かと思います。

これで問題の切り分けができなかった場合は、CameraActorのアクタに対して原点座標が書き込まれた際にコールスタックを吐かせるといった、別の追跡手段のご提案をさせていただく予定です。​

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

[Attachment Removed]

申し訳ございません、本件こちらの不手際が原因で解決することができました。

今後の参考に、下記の方法について教えていただきたいです。

>>CameraActorのアクタに対して原点座標が書き込まれた際にコールスタックを吐かせるといった、別>>の追跡手段のご提案をさせていただく予定です。

なお、本件はクローズとさせて下さい

[Attachment Removed]

ご連絡ありがとうございます。

解決されたと聞き、安心いたしました。

> 今後の参考に、下記の方法について教えていただきたいです。

>> CameraActorのアクタに対して原点座標が書き込まれた際にコールスタックを吐かせるといった、別

>> の追跡手段のご提案をさせていただく予定です。

承知しました。こちらの件ですが、エンジンを改造して上の主旨のコードを仕込むというアプローチになります。

Engine\Source\Runtime\Engine\Private\Actor.cpp の include 群の最後に下記の2ヘッダぶんを追記していただき、

#include "WorldPartition/ActorInstanceGuids.h"
#include "Engine/CoreSettings.h"
+ #include "Camera/CameraActor.h"
+ #include "Misc/AssertionMacros.h"
 
DEFINE_LOG_CATEGORY(LogActor);

同.cppファイルのSetActorLocation​()関数の先頭に下記の要領でコードを挿入してください。

bool AActor::SetActorLocation(const FVector& NewLocation, bool bSweep, FHitResult* OutSweepHitResult, ETeleportType Teleport)
{
+	if (ACameraActor* CameraActor = Cast<ACameraActor>(this))
+	{
+		if (NewLocation.IsNearlyZero())
+		{
+			FDebug::DumpStackTraceToLog(TEXT("CameraActor was set to ZeroVector. Call stack:"), ELogVerbosity::Warning);
+		}
+	}
 
// 以下割愛

​SetActorLocationAndRotation()にも同様のコードの仕込みが必要です。

そのほか、​

・ActorReplication.cppのPostNetReceiveLocationAndROtationでNewLocationをテスト

・SceneComponent.cppでSetRelativeLocation_Direct()でNewLocationをテスト(型チェックはGetOwner()に対して行う)

あたりにもコードを仕込んでおけば万全となります(各ファイルにおいて前述の include 2行の追加をお願いします)。

もし今後必要な機会がありましたらご利用ください。

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

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

[Attachment Removed]