リプレイ
イントロダクション
このドキュメントでは、Quantumシミュレーションのリプレイを保存・再生する方法について説明します。システムのすべての部分はソースコードの形で提供されます。実装は調査可能で、そのまま使用したり、より良い方法でプロジェクトの要件に対応するよう調整もできます。
リプレイは、記録されたセッションから、全く同じユーザー入力とゲームアセットでゲームシミュレーションを再実行する、変更されていないコンパイル済みのアプリケーションです。また、デフォルトのランナー以外に2つ目のランナーを実行し、例えばkillcamリプレイの実行に使用することも可能です。コンパイル済みのアプリケーションはAndroid、Unity Editor、Windows exe、カスタムゲームサーバーなど同じものである必要はなく、同じプラットフォームで実行する必要もありませんが、同じQuantum dllで構築されている必要があります。
Quantumリプレイの実行には、以下の4つのパートが必要です:
- 同じQunatumライブラリバージョンを持つアプリケーションビルド
- PhotonDeterministic.dllとquantum.core.dll
- カスタムのquantum.code.dll
- ゲームアセット
- Quantumアセットデータベース(DB)
- LUTファイル(数学用のFPルックアップテーブル、通常は変更されません)
- ゲームセッション固有のコンフィギュレーションファイル
- SimulationConfig
- RuntimeConfig
- ゲームセッション固有の入力履歴
ファイルの再生
アセットDB
Quantumでリプレイを再生するには、リプレイが記録されたすべてのゲームアセットと全く同一のバージョンが必要です。バージョン管理されたQuantumのアセットDBで起動する必要があります。DBはUnityからJsonファイル(db.json)にエクスポート可能です。
C#
var serializer = new QuantumUnityJsonSerializer();
var data = serializer.SerializeAssets(UnityDB.DefaultResourceManager.LoadAllAssets(true));
File.WriteAllBytes(“db.json”, data);
コンフィギュレーションファイルと入力履歴
利便性のためAPIとスクリプトで使用されるデフォルトのリプレイフォーマットは1つのクラスで構成され、Json(replay.json)を使用してシリアル化されてファイルとして保存されます。このフォーマットには、必要な部分の (3) と (4) が含まれ、さらにオプションで開始するフレーム (Frame
, InitialFrame
, InitialFrameData
) を格納できます。
サイズとパフォーマンスが考慮される場合、任意のバイナリシリアライズを追加可能です。必要なクラス(例えば DeterministicTickInputSet
)はかなりシンプルです。また、スニペットも提供しています。
関連クラス: quantum.code/Replay/ReplayFile.cs
C#
var serializer = new QuantumUnityJsonSerializer();
var replay = QuantumRunner.Default.Game.GetRecordedReplay();
var data = serializer.serializer.SerializeReplay(replay);
File.WriteAllBytes(“db.json”, data);
チェックサム
SessionConfigでフレームチェックサムが有効になっている場合、それらをキャプチャしてファイルに保存できます。リプレイの再生時には新しく生成されたチェックサムを記録されたものと照合し、シミュレーションが正しいか確認します。チェックサムの計算にはコストがかかるため、これは開発機能としてのみ認識されています。
関連クラス: quantum.code/Replay/ChecksumFile.cs
C#
var serializer = new QuantumUnityJsonSerializer();
var data = serializer.SerializeChecksum(QuantumRunner.Default.Game.RecordedChecksums);
File.WriteAllBytes(“db.json”, data);
Unityでのリプレイの保存
RecordingFlagsの設定
Quantumゲームの開始時には、開始パラメータQuantumRunner.StartParameters.RecordingFlags
内の必要なRecordingFlags
を設定します。
QuantumRunnerLocalDebug
スクリプトには切替可能なメンバーがあります。カスタムメニュークラスから開始する場合には、コードで明示的に設定する必要があります。
C#
[Flags]
public enum RecordingFlags {
None = 0,
Input = 1 << 0,
Checksums = 1 << 1,
Default = Input | Checksums,
All = 0xFF
}
リプレイのエクスポート
Unity Editorメニュー Quantum > Export > Replay (JSON)を使用し、ファイルの保存先フォルダを選択します。
メソッドReplayMenu.ExportDialogReplayAndDB()
を検索し、DBと再生ファイルのエクスポートに必要なコードを参照します。
リプレイAPI
StartParameters
とシリアライザーのほか、QuantumGame
クラスはその他の関連するリプレイメソッドを保持しています。
C#
public class QuantumGame : IDeterministicGame {
public InputProvider RecordedInputs { get; }
public ChecksumFile RecordedChecksums { get; }
public ReplayFile GetRecordedReplay();
public void StartRecordingInput(Int32? startFrame = null);
public void StartRecordingChecksums();
public void StartRecordingInstantReplaySnapshots();
public void StartVerifyingChecksums(ChecksumFile checksums);
}
もう1つの重要な部分はInputProvider
クラスです。これはQuantum入力システムと、読込/保存可能なものの間でアダプターとして機能するよう設計されています。
このクラスは入力の記録(QuantumGame.RecordedInputs
およびInjectInput()
)、保存やロード (ImportFromList()
およびExportToList()
)、シミュレーション用に入力の再生(StartParameters.ReplayProvider
)をおこなう際に使用されます。
Unityでのリプレイの再生
ローカルゲームを開始するスクリプトと同様に (QuantumRunnerLocalDebug
) 、QuantumRunnerLocalReplay
スクリプトはリプレイファイルからゲームを開始および再生します。
replay.jsonファイルを、リプレイ実行スクリプトのReplay Fileという名前のフィールドにドラッグアンドドロップします。DBおよび任意のチェックサム用のその他のファイルが自動的にアサインされます。アサインされない場合には、それぞれのフィールドに2つのファイルをドラッグします。DatabasePath
フィールドはもう使用されません。
QuantumRunnerLocalReplay.cs
スクリプトを検索し、リプレイファイルでゲームを開始するのに必要なすべてのアクションを調査します。
リプレイファイルのデシリアライズ
C#
var serializer = new QuantumUnityJsonSerializer();
var replayFile = serializer.DeserializeReplay(ReplayFile.bytes);
var assets = serializer.DeserializeAssets(DatabaseFile.bytes);
var checksums = serializer.DeserializeChecksum(ChecksumFile.bytes);
開始パラメータの設定
- リプレイファイルから
SessionConfig
とRuntimeConfig
を設定します。 - ロードされ、デシリアライズされた入力履歴から新しいインスタンスを作成し、
ReplayProvider
を設定します。 GameMode
をReplay
に設定します。PlayerCount
とLocalPlayerCount
をSessionConfig
から設定します。このモードではすべてのプレイヤーがローカルとみなされます。- 任意でInitialFrameとFrameDataを設定します。
- デシリアライズされたアセットDBを使用し、
ResourceManageOverride
を新しいインスタンスに設定します。
C#
var param = new QuantumRunner.StartParameters {
RuntimeConfig = replayFile.RuntimeConfig,
DeterministicConfig = replayFile.DeterministicConfig,
ReplayProvider = new InputProvider(replayFile.InputHistory),
GameMode = Photon.Deterministic.DeterministicGameMode.Replay,
RunnerId = "Replay",
PlayerCount = replayFile.DeterministicConfig.PlayerCount,
LocalPlayerCount = replayFile.DeterministicConfig.PlayerCount,
InstantReplayConfig = InstantReplayConfig,
InitialFrame = replayFile.InitialFrame,
FrameData = replayFile.InitialFrameData,
ResourceManagerOverride = new ResourceManagerStatic(assets, new QuantumUnityNativeAllocator())
};
Quantumゲームの起動
C#
var runner = QuantumRunner.StartGame("Replay", param);
リプレイを再生し、任意でチェックサムの確認を開始
C#
runner.Game.StartVerifyingChecksums(checksums);
コンソールランナー
コンソールランナーはSDKとともに配布されます。単純なDotnetコンソールアプリケーションで、Unity外のリプレイからQuantumシミュレーションを実行できます。
quantum.console.runner
プロジェクトはquantum_codeソリューションに追加できます。このプロジェクトは、デフォルトではアセンブリフォルダ内のQuantum dllとコードソリューションを参照します。
スタートアッププロジェクトとしてプロジェクトを選択するか、または以下のStartArgumentsをプロジェクトのデバッグ用に設定してF5でデバッグを実行します。リプレイファイルはquantum_unity/Assets/Resources/replay
に格納されると予期されます。
<StartArguments>../../../../quantum_unity/Assets/Photon/Quantum/Resources/LUT ../../../../quantum_unity/Assets/Resources/replay/db.json ../../../../quantum_unity/Assets/Resources/replay/replay.json ../../../../quantum_unity/Assets/Resources/replay/checksum.json</StartArguments>
またはコンソールアプリをコンパイルし、以下のパラメータで実行します。
C#
console.runner.exe [folder path to LUT files] [file path to database] [file path to replay] ([file path to checksums])
警告:リプレイランナーが正常に作動するには、イントロダクションで説明した一連のライブラリ、DB、設定、入力を正確に設定する必要があります。
警告:検証エラーが発生する場合は、プラットフォームの互換性が原因である可能性があります。Unityで記録されたチェックサムは、Dotnetランナーで生成されたものと互換性がありません。SessionConfigでChecksumCrossPlatformDeterminism
を有効にし、リプレイを再度記録するとエラーが修正されます。
インスタントリプレイ
ゲーム中に発生するkillcamリプレイのようなインスタントリプレイを補助的なQuantumRunnerでおこない、インスタントリプレイが終わるとデフォルトランナーに戻る方法を示すスクリプトを提供しています。
このスクリプトを使用するには、QuantumInstantReplayDemo
という名前のコンポーネントを追加してセットアップをおこない (再生速度やリプレイの長さなどを設定)、ゲームプレイ中にスタートおよびストップボタンを押します。