DemoNetDriver とストリーマー

ゲームプレイを記録し再生するためのリプレイ システムの概要を説明します。

Choose your operating system:

Windows

macOS

Linux

DemoNetDriver は、 ストリーマー を使って、リプレイを作成するために必要な情報の抽出と記録を行います。エンジンには、リプレイ データがどのように見えるようにするかに応じて、異なるストリーマーを DemoNetDriver にアタッチすることができるさまざまなストリーマーが含まれています。デフォルトの Local File Streamer はホスト マシンからイベントを直接ディスクに記録します。シングル プレイヤー ゲームや、ホスト プレイヤー自身のマシンにローカルでリプレイを続けるゲームに最適です。Local File Streamer のバリアントである Save Game Streamer はリプレイを保存ゲームスロットに記録します。これはコンソールでは特に有用で、これらのリプレイを再生および管理する補助的機能をサポートします。 Memory Streamer はクライアント マシンで実行し、メモリにデータを保存します。スポーツ作品のビデオ判定機能やシューティング ゲームのキルカメラに最適です。最後に HTTP Streamer はリプレイ データを LAN またはインターネット上の 2 台めのマシンに送ります。Dedicated サーバーのゲームやプレイヤーに反応し続けながら大勢の観戦者に向けてストリーミングする必要があるゲームに適しています。

DemoNetDriver 機能

  • DemoNetDrivers は、デフォルトで Local File Streamer を使用します。ただし、これは別の Streamer Factory のモジュール名に設定された URL オプション "ReplayStreamerOverride" を受け取ることで、オーバーライドすることができます。例えば、"InMemoryNetworkReplayStreaming" や "HttpNetworkReplayStreaming" などが考えられます。デフォルト値である "LocalFileNetworkReplayStreaming" は、プロジェクトの DefaultEngine.Ini ファイルの "NetworkReplayStreaming" セクションにある "DefaultFactoryName" 変数を設定することで変更できます。これは、 InitBase を呼び出して、適切な URL 引数をパラメータとして指定することでも行うことができます。

  • DemoNetDrivers は、リプレイ データを記録する時間の負荷をならすことができます。これを行うには、 "demo.CheckpointSaveMaxMSPerFrame" CVar を正の値に設定します。1 フレームあたりの時間制限になる前にリプレイに記録されないアクタは、記録のために次のフレームにキューします。この機能のメリットは、チェックポイントの記録とテイクの時間の長さに上限を設け、ゲームにヒッチが生じないようにします。欠点は、再生中に若干視覚的エラーが生じることです。これは、チェックポイントに、別のフレームからのアクタのデータが含まれることによって生じます。この機能はチェックポイントを記録するために指定した時間制限よりもゲームが長時間かかる場合に限り有効になります。つまり、主にローエンドのマシンに適用されること、またはパフォーマンス重視のゲームに適用されます。

  • bPrioritizeActors が true の場合、リプレイに保存されているアクタは記録順の優先度に応じて、 GetReplayPriority 仮想関数に基づき事前にソートされます。これは MaxDesiredRecordTimeMS を介して記録をならす機能と組み合わせると便利です。

  • チェックポイントの記録頻度は CVar demo.CVarCheckpointUploadDelayInSeconds を変更することで調整することができます。デフォルトは 30 秒です。チェックポイント間の時間の長さを伸ばすと、後方へスクラブまたはリプレイのスキップが遅くなりますが、リプレイのサイズは小さくなります。

  • デモを記録中に一時停止するために、変数 bPauseRecording を true に設定することができます。false に設定しなおすと記録が再開します。

  • Game Mode は、リプレイを見る場合に、異なる Player Controller クラス ( ReplaySpectatorPlayerControllerClass として指定) を使います。

  • SetViewerOverride を使用し、記録目的で使用される代替の Player Controller を作成することで、 DemoNetDriver がアクタのネットワークの関連性、カリング、および優先順位がどのように決められるかを変更することができます。これは大きなマップがあるゲームで特に有用です。プレイヤーはライブ プレイ中は遠くで起こっている物事を必ずしも認識していませんが (効率とチートを防ぐため) 、リプレイではすべて見えることを期待します。

  • DemoNetDrivers は Slate と並行して機能することができます。これを行うには "tick.DoAsyncEndOfFrameTasks" と "demo.ClientRecordAsyncEndOfFrame" CVar の両方が非ゼロでなければなりません。

リプレイが生成したアクタは、ライブ ゲームプレイのアクタと同様に関数呼び出しをします。これは、最小限のリプレイ データを持つライブ アクタのような挙動をしますが、 GameInstance GameState 、または GameMode のような共有オブジェクトに影響を及ぼす関数呼び出しは、なおもリプレイ アクタによって使用可能であり、意図しないやりかたでゲームのステートに影響を及ぼすことも意味します。これは、ライブ ゲームプレイがまだ実行中にリプレイを見ることができる Memory Streamer の場合に特にあてはまります。影響を及ぼすべきではないものに影響を及ぼすアクタから保護するために、まず、アクタがライブまたはリプレイのレベルの一部であるかをチェックし、それに応じたふるまいをするようにします。これはゲーム固有の問題であることが多く、ケースバイケースで各プロジェクトで処理しなければなりません。例えば、あるゲームではリプレイ中にプレイヤーのヘルスバーやフルスクリーンのダメージのオーバーレイを更新するが、プレイヤーのスコアは変更しない場合があるかもしれません。

リプレイ データの形式

データに関してリプレイには、3 種類のゲーム ステート情報といくつかのテキスト データがあります。最初に、ゲーム ワールドの開始ステートを表すベースライン データがあります。ワールドに対する (ベースラインからの) 正味の変化のスナップショットとしての役割を果たすチェックポイントが定期的にユーザー定義の間隔で表示されます。チェックポイント間は、ワールドの個々のオブジェクトに対する漸進的変化で満たされます。ワールドを開始ステートに初期化することでゲームの任意の瞬間を迅速かつ正確に再構築することができます。選択した時間よりも前の最終チェックポイントで表される変化を加えて、次に最新のチェックポイント後から必要な時点までの漸進的変化を適用します。リプレイに含まれるテキスト データには、player-facing リストを作るときに使用可能な表示名、ユーザー定義のテキスト タグ (HTTP Streamer のみ) が含まれます。これはゲームのリストを検索したり、フィルタリングするときに使用できます。

Local File Streamer

Local File Streamer はリプレイ データをローカル ストレージ上の単一のファイルに非同期に記録します。これは Null Streamer の代わりにエンジンの 4.20 に導入された時点のデフォルトのストリーマーです。Local File Streamer の単一ファイルへの出力は、保存されたリプレイの配布と管理を容易にし、非同期の記録はコンソールなどのハードドライブの速度を下げることでシステム上のパフォーマンスを改善します。リプレイ データ ファイルはプロジェクトの「Saved/Demos/」フォルダへ保存され、拡張子「.replay」が付きます。

Local File Streamer は Null Streamer で記録されたリプレイとは互換性がありません。プロジェクトで Local File Streamer を使用しながら、Null Streamer で記録されたリプレイと互換性を持たせるには、Null Streamer をインクルードする必要があります。これにより、今後プロジェクトで Local File Streamer が使用できなくことはありません。

SaveGame Replay Streamer

リプレイを savegame スロットへ転送する機能を追加する SaveGame Replay Streamer は Local File Streamer の特別なバージョンです。クライアント側のリプレイを保存し、それからプラットフォームの通常のインターフェース経由で保存されたゲームを取り込むコンソールでは特に有用です。このストリーマーは savegame システムがなくてもリプレイの格納、保存、取り込み機能がありますが、本来の目的は補助的 API で、savegame スロットにコピーされていないリプレイを特定し、ローカル ファイルと savegame スロットの両方からリプレイのコピー、再生、削除を行います。

Null Streamer

Null Streamer はリプレイ データをローカル ハード ドライブなどのディスクに直接書き込みます。これは、特にシングル プレイヤーのゲームなどローカルの記録に適した方法です。こうした記録はゲームプレイ トレーラーやインゲームのカットシーンを制作するなど様々な用途で役立ちます。またはゲーム内でスピードランまたはチュートリアルの動画をを見たり共有したりすることができます。リプレイのデータ ファイルはプロジェクトの「Saved/Demos/(Replay Name) 」フォルダに保存されます。

NULL Streamer はリプレイを記録するデフォルトの方法です。非推奨となっていますが、古いリプレイの再生による下位互換性はサポートします。

Memory Streamer

Memory Streamer はローカル マシンのメモリにユーザー設定の長さのリプレイデータを保持します。この種のストリームは、最近の劇的瞬間の即時リプレイに最適です。スポーツ ゲームのスコア、シューティング ゲームのデス、アクション ゲームのボス戦の最後の瞬間などが考えられます。

Memory Streamer 使用の詳細

Memory Streamer は、一回のセッション中にゲームプレイを記録、再生、ゲームプレイを再開するという点で特殊です。プレイヤーがリプレイを見ている間、ライブ ゲームは目に見えないところで、静かに継続します。これはリプレイが終了した瞬間にゲームをシームレスに再開できるようにするためです。ロード時に、エンジンはレベルを以下の 3 つのグループで集めます。すなわち、Static Levels、 Dynamic Source Leves、および Dynamic Duplicated Levels の 3 つです。こうしたグループによって、以下のようにレベルがどのようにライブ ゲームプレイとリプレイ システムとインタラクションするかが決まります。

レベル コレクション

このコレクションに追加されたレベル

ビヘイビア

Static Levels

パーシスタント レベルではないレベルであり、 IsStatic boolean のマークが付いているレベルです。

ゲームプレイの影響はうけません。ライブ プレイとリプレイ中の両方で見えます。

Dynamic Source Levels

パーシスタント レベルと IsStatic boolean 変数が false に設定されたサブレベルです。

ライブ ゲームプレイの影響を受けます。リプレイ中は非表示ですが、ゲームプレイは通常どおり実行しています。

Dynamic Duplicate Levels

ロード時に Dynamic Source Level から作られたコピーです。専用サーバーまたはエディタ モードでは存在しません。

ライブ ゲームプレイ中には非表示になります。リプレイはこうしたレベルで行われた後、空になります。

[Is Static] 設定は、Window メニューから Levels ビューを起動すると表示されます。サブレベルをハイライトした状態で [Level Details (レベルの詳細)] ボタンをクリックします。

Sublevel.png

そこから、[Level Details] ウィンドウで [Is Static] オプションを利用することができます。このウィンドウは パーシスタント レベルでは空であるため、必ずサブ レベルを選択するようにしてください。

IsStatic.png

レベル コレクションは、レベル ストリーミング プロセスの一部であり、リプレイ システムには特に関連はありません。

こうしたシステムでは、Dynamic Source Level に対してひとつの DemoNetDriver を作成し、Dynamic Duplicate Level に対してもうひとつ DemoNetDriver を作成することができます。その結果、Dynamic Source Level でライブ ゲームプレイを記録して、Dynamic Duplicate Level でそれを再生することができます。Dynamic Source Level を隠して、リプレイ中に Dynamic Duplicated Level を表示することで、ゲームはプレイを継続し、リプレイによる影響を受けないネットワークの更新を受け取ることができます。3 つめのグループである Static Level はいつでもアクティブで可視状態になります。ライブ ゲームプレイの影響を受けない静的なワールド ジオメトリや環境音、パーティクル、アニメーションのようなものを含みます。従ってリプレイ プロセスに含む必要はありません。リプレイが終了すると、Dynamic Duplicate Level のコンテンツは破棄され、ガーベジ コレクションの対象になり、Dynamic Source Level は再び可視 / 可聴になります。Dynamic Source Level は決して破棄されたり、一時停止せず、非表示であるだけなので、リプレイを見ている間、ゲームは自然に進捗し、ただちに処理落ちなしで表示可能です。さらにこのシステムでは、レベルに static とマーク付けする機能があり、リプレイの記録と再生から除外することができます。その結果、メモリと時間を節約することができます。

HTTP Streamer

HTTP Streamer はリプレイ データを、LAN 上またはインターネット上のどこかにある別のサーバーに送信します。これはライブ ストリーミングの対戦で役立ちます。またはいつでも見ることができる対戦の記録を維持するために役立ちます。このストリーマーは、専用サーバーだけがいつでもゲーム内で起こっていることをすべて把握している場合に、専用サーバーのゲームで特に役立ちます。リプレイ データを処理する作業から解放すると、単一サーバーで同時にホスト可能なゲーム数が増えます。モデレーションやチート検出ツールとしても機能します。ゲームを実行する当事者によって完全に制御されるコンピュータからデータをキャプチャーできるからです。

HTTP Streamer 使用の詳細

HTTP Streamer は、GET メソッドと POST メソッドを使ってデータをバイナリまたは JSON 形式の文字列で送信し、 HTTP Streamer REST API を通してカスタム記述されたリプレイ サーバーと通信します。独自のリプレイ サーバーを設定するには、最初に URL を設定しなければなりません。プロジェクトの DefaultEngine.Ini ファイルには、リプレイ サーバーの URL が [HttpNetworkReplayStreaming] セクションの変数、 ServerURL にあります。 ServerURL は、"http://replay.yourgame.com/" の形式になるようにします。最後の "/" の部分は重要です。HTTP Streamer は URL の形式を修正しないことを前提にしているからです。

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