プロパティのレプリケーション

Actor プロパティのレプリケート方法について詳しく説明します。

それぞれの アクタ は、Replicated Specifier を含むすべてのプロパティのリストを保持しています。レプリケートされたプロパティが値を変更するたびに、サーバーはクライアントに更新値を送信し、それをクライアントはローカル上のアクタに適用します。プロパティ更新はサーバーのみが送信します。クライアントがプロパティの更新をサーバー側またはその他のクライアントへ送信することはありません。

クライアント側でレプリケートされた変数の値を変更することは推奨されません。サーバーが変化を探知して更新を送信するまで、クライアント上の値はサーバーの値を異なり続けてしまいます。サーバー側にあるプロパティのコピーが頻繁に変更されない場合、クライアントが修正を受け取るまでに時間がかかる可能性があります。

アクタのプロパティのレプリケーションには高い信頼性があります。つまり、アクタのクライアント バージョンのプロパティには最終的にサーバー上の値が反映されます。ただし、クライアントは必ずしもサーバー上のプロパティで発生するすべての個々の変更の通知を受け取るとは限りません。例えば、整数プロパティの値が「100」から「200」に急激に変更され、その後「300」に変更された場合、クライアントは最終的に「300」という値の更新を受け取りますが、クライアントが「200」への変更について認識することは保証されません。

レプリケーション用のプロパティを設定

プロパティのレプリケーションにはいくつかの設定が必要です。 プロパティを定義したアクタクラスのヘッダに、 UPROPERTY 宣言へのパラメータの 1 つとして replicated キーワードがあることを確認してください。

    class ENGINE_API AActor : public UObject
    {
        UPROPERTY( replicated )
        AActor * Owner;
    };

アクタ クラスの実装で、次のように GetLifetimeReplicatedProps 関数を実装する必要があります。

    void AActor::GetLifetimeReplicatedProps( TArray< FLifetimeProperty > & OutLifetimeProps ) const
    {
        DOREPLIFETIME( AActor, Owner );
    }

アクタのコンストラクタで、bReplicates フラグが true に設定されていることを確認します。

    AActor::AActor( const class FPostConstructInitializeProperties & PCIP ) :Super( PCIP )
    {
        bReplicates = true;
    }

メンバ変数 Owner は、現時点でインスタンス化されているこのアクタ型のすべてのコピーを接続先クライアントすべてに同期します (この場合は基底アクタ クラス)。

ネットワーク更新の最適化

データ手動のネットワーク更新頻度

アクタは NetUpdateFrequency 変数で設定された最大更新頻度に従います。重要度の低い、あるいは頻繁に変化されないアクタでこの変数を減らすことにより、ネットワークの更新をより効率的に実行することができ、帯域幅が制限されたシナリオでのよりスムーズなプレイ体験につなげることができる可能性があります。一般的な更新頻度値は、シューティングゲームでプレイヤーがコントロールする予測不要のアクタなど重要なアクタの場合 10 (0.1 秒ごとに更新)、co-op ゲームで AI がコントロールする動きの遅いモンスターなどその他のアクタは 5 (0.2 秒ごとに更新)、ゲームプレイでの重要性は低いながらもネットワーク上で同期され、サーバー側のロジックでコントロールされるためレプリケーションが必要なバックグラウンド アクタの場合は 2 (0.5 秒ごとに更新) です。

適応ネットワーク更新頻度

この機能はデフォルトではオフになっています。コンソール変数を net.UseAdaptiveNetUpdateFrequency1 に設定することで有効になります。

適応ネットワーク更新頻度 (Adaptive Network Update Frequency) を使用することで、実際は何も変更されていないにもかかわらず、アクタをレプリケートしようとする重複した動作によって無駄になりがちな CPU サイクルを節約することができます。この機能を有効にすると、システムは個々のアクタの更新が有意であるかどうかに基づいて、個々のアクタの更新頻度を動的に調整します。この場合の「有意な」更新とは、アクタの初期化、サブオブジェクト (すなわち、所有コンポーネント) の追加または削除、またはアクタまたはそのサブオブジェクトのレプリケートされたフィールドの値の変更を行う更新のことを指します。各アクタの更新頻度の可能な範囲は、アクタ自体の 2 つの変数 NetUpdateFrequency および MinNetUpdateFrequency によって決定されます。NetUpdateFrequency は、アクタがアクタ自身の更新を試みる 1 秒あたりの最大回数を示し、MinNetUpdateFrequency は 1 秒あたりの更新試行の最小回数を示します。この新しい機能を使うと、レプリケーションのパフォーマンスが大幅に改善されます!

(上級者向け) 更新頻度減少のアルゴリズム

更新の試行中に、アクタは有意な最新の更新が送信されてからの時間を特定し、アクタが有意な更新を送信した場合はその新しい時間を記録します。更新の対象となるアクタが有意な更新を 2 秒以上送信しなかった場合、そのアクタは更新頻度の削減を開始し、有意な更新がない場合は 7 秒後に最小頻度に達します。例えば、0.1 〜 0.6 秒の更新遅延が設定されているアクタが 3 秒間有意な更新を行わなかった場合、そのアクタは次の更新を 0.2 秒で試行します。

(上級者向け) 更新頻度増加のアルゴリズム

有意な更新の送信後、アクタは次の更新を、最小更新頻度と最大更新頻度の範囲内で、最新の 2 つの有意な更新の間の時間よりも 30% 短い時間で行うようにスケジュールします。例えば、アクタで有意な更新が厳密に 1 秒の間隔で行われた場合、その後は 0.7 秒 (または指定された最小および最大更新頻度に近い時間) で次の更新が試行されるようにスケジュールします。連続する有意な更新が行われるたびにこの計算が繰り返され、アクタが頻繁にデータまたはサブオブジェクトを変更し始めた場合は、更新間隔が迅速に短縮されます。

Unreal Engine のドキュメントを改善するために協力をお願いします!どのような改善を望んでいるかご意見をお聞かせください。
調査に参加する
キャンセル