新機能紹介
Quantum SDKがUnitypackageになりました
Unitypackageになったことで、初期設定やアップグレードが誰でも簡単になりました。将来的には、アセットストアやUPMで配布する予定です。
QuantumGame
(以前まではquantum.code
プロジェクト)のソースは、Unityのアセット側(Assets/QuantumUser/Simulation
)に移動しました。- Unity CodeGenステップは削除され、すべてのコード生成はUnity Editor中のQtn/DSL CodeGenで行われます。
- Unityとの統合を整理するため、相当数のQuantumの型やスクリプトが移動/リネーム/マージされます。マイグレーション中、スクリプトのGUIDは保存され、コンパイルエラー数を減らすため、廃止されるスクリプトの旧名称が
QUANTUM_ENABLED_MIGRATION
から与えられます。 [SerializeReference]
やOdin固有のシリアライズ拡張を含む、Unity/Odinのプロパティ属性が自由に使用できます。ただし、決定論的ではないUnityのAPIが非推奨であることは変わりません。- 新規アセットには決定論的な
AssetGuid
が与えられます。これによって、すべてのQuantumアセットはローディングなしに収集されるため、処理速度が劇的に向上します。 AssetObject
がScriptableObject
になり、AssetBase
は不要になりました。これによって、アセットのヒエラルキーはより柔軟になり、partialクラスを拡張するモデルには制限されなくなりました。- レガシーコードを削減するため、最小Unityバージョンが
2021 LTS
に引き上げられました。
例えば.Netコンソールアプリケーション上やカスタムサーバープラグイン上で、Unityに依存せずにシミュレーションDLLをコンパイルすることも可能です。
SDKの内容の詳細はQuantum Projectをご覧ください。
Quantumアセンブリ名の変更
以下のQuantumライブラリはリネームされました。
PhotonDeterministic.dll
->Quantum.Deterministic.dll
quantum.core.dll
->Quantum.Engine.dll
quantum.code.dll
->Quantum.Simulation.dll
入力のデルタ圧縮
入力メッセージはデフォルトでデルタ圧縮されるようになったため、通信量が劇的に削減されます。サーバーメッセージのネットワークトランスポートモードはReliableに変更され、Quantumの入力プロトコルは単純化しました。
デフォルトではデルタ圧縮が有効ですが、無効にすることも可能です。
リプレイもデルタ圧縮された入力が保存されるため、サイズが非常に小さくなります。
プレイヤー追加/削除の新プロトコル
Quantumの開始プロトコルは、最初に枠を予約せずに、実行時にプレイヤーの追加/削除ができるように変更されました。
AddPlayer()
とRemovePlayer()
が、SendPlayerData()
を置き換えます。SendPlayerData()
とは異なり、AddPlayer()
はスロットごとに一度だけ送信できます。
シミュレーションは、ISignalOnPlayerAdded
とISignalOnPlayerRemoved
シグナルから、プレイヤー追加/削除に反応できます。
ビューは、CallbackLocalPlayerAddConfirmed
とOnLocalPlayerRemoveConfirmed
から、ローカルプレイヤーのスロット追加に反応できます。同様に、OnLocalPlayerAddFailed
とOnLocalPlayerRemoveFailed
から、そのエラーに反応できます。
AddPlayer()
はサーバー側で送信頻度に制限があるため、スパムはできません。
API全体を通して、プレイヤー(PlayerRef
)とプレイヤースロット(ローカルプレイヤー)を明確に区別するため、パラメーター名がわずかに変更されています。
Player
は常に実際のグローバルなプレイヤーのインデックスを参照しますが、PlayerSlot
は常にローカルのプレイヤースロットを参照します。プレイヤースロットは、例えば、一つのクライアントで複数のプレイヤーを制御する際に使用されます。ローカルのプレイヤースロットを一つだけ使用するなら、そのスロットは0
になります。
例えば、入力コールバックCallbackPollInput
はPlayerSlot
プロパティを使用するようになり、QuantumGame.AddPlayer(Int32 playerSlot, RuntimePlayer data)
にも、ローカルのプレイヤースロットを識別するための明確な名前のパラメーターがあります。
詳細はPlayerをご覧ください。
予測コマンド
コマンドは、次の予測フレームから直ちに実行可能になりました。これは以前から要望のあった機能ですが、新バージョンで入力プロトコルを改善したことで、この機能がついに実現できるようになりました。
送信したコマンドは、次の予測フレームに追加され、検証済みでないフレームでも実行可能になります。実際に予測されるティック値は99.9%正確です。
これにより、コマンドの応答性が向上し、変更を速やかにゲームプレイに反映できます。
Webhook
Webhookは、独自のバックエンドによってゲームの安全性を高めるものです。ルーム作成・ルーム参加・RuntimePlayer
・RuntimeConfig
は、HTTPリクエストを使用するバックエンドから傍受・検証できます。
Webhookによって、サーバーから直接リプレイのストリーミングも可能です。
これらは、Photonのダッシュボードから有効化・設定できます。
詳細はWebhook Online API Documentationをご覧ください。
Quantum 3 AppId
Quantum 3のアプリケーションは、Photon Dashboard上から、Quantum 3 AppIdを作成する必要があります。
詳細はQuantum Asteroids Tutorial - Project Setupをご覧ください。
Photon Realtime 5
Realtimeの新メジャーバージョンには.Netのasync拡張が含まれるため、ネットワーク接続周りの記述・制御がしやすくなります。
Photon Realtimeのリリースノートを必ずお読みください。
Photonクライアントの接続を開始し、Photonのルームに参加するには、以下のようにawait
でメソッドを呼ぶだけです。
C#
MatchmakingArguments connectionArguments = new MatchmakingArguments {
PhotonSettings = PhotonServerSettings.Default.AppSettings,
PluginName = "QuantumPlugin",
MaxPlayers = 8,
UserId = Guid.NewGuid().ToString(),
NetworkClient = new RealtimeClient { ClientType = ClientAppType.Quantum }
};
RealtimeClient client = await MatchmakingExtensions.ConnectToRoomAsync(connectionArguments);
デフォルトでは、すべてのエラーは例外として投げられます。async APIの呼び出しは、try/catchブロックで囲う必要があります。
Realtime拡張の詳細はPhoton Async Extensionsをご覧ください。
SessionRunnerクラス
QuantumRunner
とSessionContainer
はSessionRunner
クラスにマージされ、Quantum Gameプロジェクトに置かれました。このクラスは、Photon Realtime 5ライブラリを使用しています。
Quantumのゲームセッションは、asyncでも非asyncでも開始できます。
C#
SessionRunner.Arguments sessionRunnerArguments = new SessionRunner.Arguments {
RunnerFactory = QuantumRunnerUnityFactory.DefaultFactory,
GameParameters = QuantumRunnerUnityFactory.CreateGameParameters,
ClientId = client.UserId,
RuntimeConfig = runtimeConfig,
SessionConfig = QuantumDeterministicSessionConfigAsset.DefaultConfig,
GameMode = DeterministicGameMode.Multiplayer,
PlayerCount = 8,
StartGameTimeoutInSeconds = 10,
Communicator = new QuantumNetworkCommunicator(client),
};
QuantumRunner runner = (QuantumRunner)await SessionRunner.StartAsync(sessionRunnerArguments);
awaitが完了するのは、Quantumの開始プロトコルが完了し、最初のスナップショットを受信した時です。
接続してからQuantumのシミュレーションをオンラインで開始するまでの最も簡単な方法については、QuantumSampleConnection.unity
シーンをお試しください。
新しいSDKサンプル
新しいSDKには、シンプルなAsteroidsゲームサンプルが付属しており、QuantumHubからインストールできます。
新しいデモメニュー
新しいデモメニューは、Quantum 2.1のロビーメニューサンプルを置き換えたものになります。(Unity.UIでの)見た目のアップグレードと、二つのシンプルなオンラインモード(ランダムマッチメイキング・部屋コード共有)を実装しています。
デモメニューのコードとプレハブは、SDKのunitypackage
で配布されており、QuantumHubのTutorials&Sampleセクションからインストールできます。
拡張可能性と接続ロジックの複雑性の制御はトレードオフですが、これらが適切なバランスになるように設計されています。メニューパーツの実装やプレハブは、Fusionなどの他のSDKでも使用されています。
デモシーンではTextMeshProを使用しています。最初にデモシーンが開いた時に、TMPインストールのポップアップが表示されます。
Quantum.Unityのアセンブリ定義は、TMPのUnitypackage(com.unity.textmeshpro
)が見つかった際にQUANTUM_ENABLE_TEXTMESHPRO
を設定するため、QuantumのメニューのスクリプトはTMPが無効でもコンパイルされます。
メニューのカスタマイズ方法についての情報はSample Menu Customizationをご覧ください。
RuntimeConfigとRuntimePlayerのJSONシリアライゼーション
これらファイルの手動のシリアライゼーションは、JSONに置き換わりました。ファイルがQuantumプロトコルで送信されることは変わりませんが、JSON文字列で圧縮されます。
元々のシリアライゼーションは常にメンテナンスを必要とし、面倒で、エラーの原因になっていました。さらに、WebhookのHTTPリクエストでコンフィグを送信する際に、受信したバックエンド側は、正しくデシリアライズするために元のC#コードが必要でした。
SerializeUserData()
メソッドは廃止されました。
コンフィグをバイト列にシリアライズするには、QuantumGame.RuntimePlayerSerializer
が必要です。これは開始時にSessionRunner.Argumnts
で設定できて、通常はデフォルトのQuamtumのJSONシリアライザーであるQuantumJsonSerializer
に設定されます。
C#
var runtimeConfig = new RuntimeConfig();
var runtimeConfigBinary = RuntimePlayer.ToByteArray(runtimeConfig, new QuantumJsonSerializer());
var runtimeConfigOther = RuntimePlayer.FromByteArray(runtimeConfigBinary, new QuantumJsonSerializer());
// make sure to check if runtimeConfig and runtimeConfigOther are equal to validate the json serialization
RuntimePlayer
(またはコマンド)のシリアライズ済みバイナリの最大サイズは、24kBです。もし、複数のクライアントがこの方法で大きなデータチャンクを送信した場合、一つの入力メッセージには収まらないため、サーバーが受け入れるのは次のティックになります。
Quantum Hub
重要な設定ファイルが見つからない時に、Quantum Hubがポップアップします。Fusion SDKによって、Hubウィンドウの使用が、ユーザーファイル(packageに含まれないもの)のインストールや生成を行う最も便利な方法であることが証明されました。セットアップが必要なのは一度のみで、ファイルはプロジェクトと一緒にバージョン管理されます。
Quantum CodeDoc Inspectors
Quantum Unity Inspectorsはビジュアルが更新され、XMLのインラインコードコメントからトグル可能なヘルプテキストが生成されます。
データ駆動のシステムセットアップ
Quantumで起動するシステムの選択は、ゲームモードやマップ選択によって変わります。SystemsConfig
アセットを使用して、データ駆動アプローチが導入されました。異なるシステムとサブシステムの組み合わせは、RuntimeConfig
アセットで参照されるようになりました。
Quantum 2.1の静的なSystemSetup.CreateSystems()
は動作しますが、廃止が検討されていて警告ログが出ます。このクラスは、Quantum 2.1のプロジェクトをアップグレードし、コンテンツを移行した後に削除できます。
システムは、以下の順で作成されます。(DeterministicSystemSetup.CreateSystems()
をご覧ください)
- 古い
SystemSetup.CreateSystems()
クラスとメソッドが存在する場合(リフレクションでチェックされます):これが呼び出され、残りはスキップされます - 与えられた
SystemsConfig
に登録がある場合:システムが作成・追加され、処理を継続します - 与えられた
SystemsConfig
が無効、または登録がない場合:デフォルトのシステムが作成・追加され、処理を継続します - 最後に
DeterministicSystemSetup.AddSystemsUser()
が呼び出され、仕上げを行います
古:file: quantum_code/quantum.code/SystemSetup.cs
C#
namespace Quantum {
public static class SystemSetup {
public static SystemBase[] CreateSystems(RuntimeConfig gameConfig, SimulationConfig simulationConfig) {
return new SystemBase[] {
// ..
}
}
}
}
新:file: Assets/QuantumUser/Simulation/SystemSetup.User.cs
C#
namespace Quantum {
using System.Collections.Generic;
public static partial class DeterministicSystemSetup {
static partial void AddSystemsUser(ICollection<SystemBase> systems, RuntimeConfig gameConfig, SimulationConfig simulationConfig, SystemsConfig systemsConfig) {
systems.Add(new TestSystemMainThreadGroup("TestSystemsGroup", new SystemMainThread[] { new TestSystemImmediateRemoveDestroy(), }));
systems.Add(new TasksTestSystem());
3Dカプセル形状
Quantum Physicsが、ついに2D/3Dのカプセル形状に対応しました。
最大コンポーネント数
最大コンポーネント数が512に引き上げられ、qtnファイル内で調整できるようになりました。
#pragma max_components 512
Entity Viewフレームワーク
UnityスクリプトのEntityViewComponent
を使用することで、ゲーム状態に素早く反応するビューのコードを追加できます。
Entity Viewプール
QuantumEntityViewPool
を使用して、EntityView
を簡単にプールできます。
Character Controllerアドオン
新しいカプセル状の衝突判定に基づく、新しいKinematic Character Controllerが、アドオンとして使用可能になりました。
決定論的なナビメッシュのベイク
Quantumのナビメッシュのベイクが決定論的になりました。実行時にナビメッシュを生成するゲームには朗報です。デフォルトのパイプラインはまだ、Unityの(決定論的ではない)メッシュのインポートに依存していますが、最終的には置き換わります。
ナビメッシュのベイクは、UnityからQuantumGameのシミュレーションコードに移動しました。(個別のリリースノートをご覧ください)
ダッシュボードのオプション
デフォルトでは、Quantum3のアプリケーションは、非プロトコルメッセージとプレイヤープロパティをブロックします。これらのレガシーな機能は、潜在的には悪意ある人によって、マッチメイキングやQuantum製アプリケーションのゲームプレイが阻害されてしまう可能性があります。この機能をアンロックするには、各AppIdで明示的にダッシュボードのプロパティを設定する必要があります。
BlockNonProtocolMessages
(true
/false
)BlockPlayerProperties
(true
/false
)
BlockRoomProperties(新)
データ型:boolean
(true
/false
)
プラグインは、ルーム作成後にクライアントから設定されるすべてのルームプロパティをキャンセルします。ただし、StartQuantum
プロパティは除きます。ルームプロパティの初期値は、Webhookからも取得可能です。
注意:これはOpen
やIsVisible
にも影響します。
AllowedLobbyProperties(新)
データ型:string
(有効なセパレーターは、, か ; かスペース)
最大プロパティ数:3
最大string
プロパティ長:64
マスターサーバー上でのマッチメイキングのパフォーマンスを維持するため、クライアントがロビープロパティとして送信できるプロパティのリストを設定します。このプロパティが設定されると、クライアントから送信されたリストに含まれないプロパティは除外されます。これは、プラグインのログのRestricted LobbyProperty
でわかります。
デフォルトでプロパティのデータ型は以下に制限されます:bool
, byte
, short
, int
, long
, string
MaxPlayerSlots(新)
データ型:int
デフォルトでは、クライアントはゲームがサポートしている数の分だけローカルプレイヤーを作成できます。この値を設定することで、このAppIDで実行されるすべてのゲームで、作成できる数を制限できます。この値は、Webhookからも設定できます。
StartPropertyBlockedTimeSec(新)
データ型:int
値を0より大きく設定すると、ルームが作成されてから最小秒数が経過するまで、Quantumの開始がブロックされます。これは、ゲームが開始される前に、プレイヤーに十分な参加時間を確保するために使用できます。
StartPropertyForcedTimeSec(新)
データ型:int
値を0より大きく設定すると、ルームが作成されてからQuantumが開始されるまでの最大秒数になります。設定時間が経過すると、ルームプロパティのStartQuantum
プロパティが(もしまだ設定されていなければ)trueに設定されます。
HideRoomAfterStartSec(新)
データ型:int
値を0より大きく設定すると、Quantumが開始されてから設定秒数まで、ルームがパブリックな検索やリストから隠されます。ルームの可視性を管理して、既に開始中のゲームに新規プレイヤーが参加しないことを保証できます。
CloseRoomAfterStartSec(新)
データ型:int
値を0より大きく設定すると、Quantumが開始されてから設定秒数まで、ルームへの参加が不許可になります。ルームへの参加を不許可にすることで、新規プレイヤーの参加を拒み、ゲームセッションのライフサイクルの管理に使用できます。
Back to top- Quantum SDKがUnitypackageになりました
- Quantumアセンブリ名の変更
- 入力のデルタ圧縮
- プレイヤー追加/削除の新プロトコル
- 予測コマンド
- Webhook
- Quantum 3 AppId
- Photon Realtime 5
- SessionRunnerクラス
- 新しいSDKサンプル
- 新しいデモメニュー
- RuntimeConfigとRuntimePlayerのJSONシリアライゼーション
- Quantum Hub
- Quantum CodeDoc Inspectors
- データ駆動のシステムセットアップ
- 3Dカプセル形状
- 最大コンポーネント数
- Entity Viewフレームワーク
- Entity Viewプール
- Character Controllerアドオン
- 決定論的なナビメッシュのベイク
- ダッシュボードのオプション