ブログに戻る

UEFNとUnreal Engine MultiplayerにおけるPlayer Location Desyncの修正方法

公開日 2026年2月27日
UEFNとUnreal Engine MultiplayerにおけるPlayer Location Desyncの修正方法

Multiplayer Transform Desync の悪夢

マルチプレイヤーゲームの開発者なら誰しも、netcode が「嘘」をつき始める瞬間に直面します。プレイヤーが椅子に座り、その椅子がマップ上を移動するシーケンスをスクリプトしたとします。サーバー上では完璧に見えます。しかし、2つ目のクライアントを立ち上げると、その幻想は打ち砕かれます。クライアントAには椅子に乗っている自分が正しく見えていますが、クライアントBには、椅子だけが移動し、クライアントAは開始地点の空中に固定されたままに見えるのです。

この特定の現象 — uefn player location desync — は、アタッチされたプレイヤーを保持するプロップに対して MoveTo コマンドを使用した際によく発生する問題です。サーバーは正しい絶対座標を登録していますが、simulated proxies(他のクライアント上のプレイヤー表現)が親プロップから更新された transform を継承できないために起こります。

UEFN でカスタム体験を構築している場合でも、Unreal Engine 5 で独立した dedicated server を設計している場合でも、アタッチメントの replication がなぜ失敗するのかを理解することは不可欠です。このチュートリアルでは、Network Dormancy の仕組み、なぜアタッチメントが client-side prediction を壊すのか、そして replication graph にワールド状態を強制的に認識させる方法を解説します。

なぜアタッチメントが Network Updates を妨げるのか

デシンクを修正するには、Unreal Engine が actor replication を階層的にどのように処理するかを理解する必要があります。

キャラクターがプロップにアタッチされると、その transform は親アクターに対する相対的なものになります。帯域幅を節約するため、Unreal Engine は Network Dormancy という概念を積極的に利用します。

プレイヤーが座って移動入力を止めると、サーバーの replication graph はプレイヤーアクターを dormant(休眠状態)としてフラグを立てることがあります。サーバーは「プレイヤーは独立して動いていないので、更新を送る必要はない。動いている椅子の更新だけを送ればいい」と判断してしまうのです。

デシンクの背後にある数値

  • Server Tick Rate: UEFN では通常 30Hz。
  • Prop NetUpdateFrequency: デフォルトで秒間 100 回の更新。
  • Character MinNetUpdateFrequency: 入力がない場合、秒間 2.0 回まで低下することがあります。

椅子を MoveTo で動かすと、椅子の transform は 30Hz で更新されます。しかし、アタッチされたプレイヤーが休眠状態だと、他のクライアントは相対位置を更新するための RPC (Remote Procedure Call) を受信しません。その結果、大きな視覚的デシンクが発生します。

ステップ 1: UEFN Verse での回避策

UEFN のバグレポートでは、「椅子から降りると直る」というヒントが示されています。これは、movement mode を Walking に戻すことで、サーバーが Network Dormancy をフラッシュし、絶対座標の更新を全クライアントに強制的に送信するためです。

Verse では、プレイヤーを降ろさずにプログラムでこの「フラッシュ」を再現できます。マイクロテレポートを使用して replication graph を強制的に起こします。

# [Verse コードはオリジナルを維持]

同じ座標に TeleportTo を呼び出すことで、C++ エンジンの TeleportPhysics フラグを立て、そのアクターの client-side prediction を完全にリセットします。

ステップ 2: ネイティブ Unreal Engine C++ での修正

ソースコードにアクセスできる場合は、networking API を直接操作して dormancy を管理できます。

// UE5 C++ での強制ネットワーク更新例
// [C++ コードはオリジナルを維持]

ステップ 3: バックエンドへの状態保存

リアルタイムのデシンク修正は半分に過ぎません。永続的なワールドを持つゲームでは、データベースに「正しい」絶対座標を保存する必要があります。強制的なネット更新のに、server-authoritative な transform をクエリするようにしてください。

バックエンドの構築には時間がかかります。horizOn はゲーム開発者向けに設計された Backend-as-a-Service で、リアルタイムの永続化機能を提供しています。

5つのベストプラクティス

  1. クライアントのアタッチ状態を信用しない: 常に server-authoritative な RPC で検証する。
  2. 乗り物の NetDormancy を手動管理する: 移動中は FlushNetDormancy を明示的に呼ぶ。
  3. アタッチ階層を浅く保つ: プレイヤー -> 椅子 -> 列車 -> 移動プラットフォームのような深い階層を避ける。
  4. 重要な状態変化には信頼性の高い RPC を使う: 乗り降りには NetMulticast を使用する。
  5. 降りる際の Transform を検証する: サーバー側で座標の妥当性をチェックする。

結論

マルチプレイヤーのデシンクは、ネットワーク最適化の結果として起こることがほとんどです。Network Dormancy の影響を理解すれば、Verse や C++ で強制的に更新をかけることができます。replication graph を制御し、サーバー権限を徹底しましょう。

バックエンドの拡張にお困りですか? horizOn を無料でお試しください。

このダッシュボードは以下のチームによって愛情を込めて作られています Projectmakers

© 2026 projectmakers.de

unknown-v1.91.1 / unknown-v--