bg_unitybg_unrealcircle_01circle_02facebookhatenalinkedinlogo_unitylogo_unrealpocketstartup-01startup-02startup-03startup-04 strix-engine__start-01strix-engine__start-02strix-engine__start-03strix-engine__start-04twitteryoutube

STRIXに関してお問い合わせを頂いた技術的なご質問を元に
内容を整理した上でFAQとして公開しております。
Strix Cloudについて

機能について

Type 0インスタンスで25ルームを超える数のルームを作成できますか。

タイプ0インスタンスでは同時接続数を最大100 CCUまでに制限させていただいておりますが、それ以外には特に制限を行っておりません。「最大25ルーム」という数字は、典型的なゲームにおいて良好な性能が維持できる最大ルーム数の目安として書かせていただいているものです。

良好な性能を維持できるルーム数は、ゲームが使用する同期対象オブジェクト数など様々な要因によって異なります。適正なルーム数を超えると性能が劣化し、ゲームプレイに支障が出ることがあります。そこで、ゲームタイトルごとにルームサーバーインスタンス1台あたりの最大ルーム数を制限できるようになっています。このルーム数の上限は固定値ではなく、ゲームに合わせて任意に設定いただけます。タイプ0インスタンスで25を超える値を設定いただくことも可能です (デフォルト値は100ルームです)。お客様が設定したルーム数上限に達すると、それ以上はルームが作成できなくなります。

なお、ルーム数とは直接関係しませんが、Strix Cloudではインスタンスタイプに関わらず、通信データ量が月間合計60GBまで無料とさせていただいており、このデータ量を超えると通信料金が発生します。タイプ0インスタンスは料金のお支払い方法を登録いただかなくてもお使いいただけますが、その場合に月間のデータ量が60GBに達するとインスタンスを停止させていただくことがありますのでご注意ください。

1台のサーバーインスタンスで複数のタイトルを動かすことはできますか。

  • 複数の異なるタイトルが同じサーバーを使った場合、特定のタイトルの負荷が高くなった場合に、他のタイトルにも影響が出る可能性があります。
  • 異なるタイトルのクライアントが同じルームに参加した場合、複製や同期の処理に不具合が生じる可能性があります。これはネットワークオブジェクトのタイプIDのような情報が一貫しなくなったり、STRIXのコンポーネントの設定値に不整合が起きたりするためです。これを回避するためには、ルームプロパティなどにより同一のルームに異なるタイトルのクライアントを入室させないような制御が必要になります。

Type 1からType 0へのダウングレードは可能でしょうか。

インスタンスタイプは、必要に応じていつでもダウングレード/アップグレードを行っていただけます。ただし、切り替えの際にサーバーの再起動が必要になりますのでご留意ください。

クライアントプログラムからサーバーの統計情報 (接続数、ルーム数など) を取得する方法はありますか。

全ルーム数を知るには、条件を指定せずにルームを検索し、見つかったルームの数をカウントすることにより可能です。同時に、各ルームの参加者数 (memberCountプロパティ) を合計することにより、実質的な接続数を知ることも可能です。ただし、ルーム数が多い場合は、カウント中にルームの作成削除や入退出が行われる場合があるため、得られた値は概数とお考えください。

複数のルームサーバーを使用した場合、作成されるルームの各サーバーへの振り分けはどのように行われるのですか。

Strix Cloudのアプリケーションを複数の人で管理できますか。

複数の方が共同で管理したい場合は、それらの方々が共用するアカウントを作成いただけば可能です。ただし、共用アカウントはセキュリティ上の問題が発生する可能性がありますので、十分注意してご利用ください。

停止中のインスタンスは課金の対象になりますか。

Strix Cloudの料金は、インスタンス使用料、インスタンス管理料、データ通信料という3種類の料金の合計になります。このうち、インスタンス使用料とデータ通信料につきましては、インスタンスを停止している間は課金されません。ただしインスタンス管理料は、Type 1以上のインスタンスであれば、停止しているインスタンスも課金の対象になります。

サーバーインスタンスを長時間動かし続ける場合、定期的に再起動することはできますか。

Strix Cloudで提供するサーバーインスタンスは、長時間連続して動作させても安定稼働するように設計されています。特に定期的に再起動を行う必要はありません。もちろん、定期的に再起動する運用でお使いいただくことで一層の安定稼働が期待できますが、そのための機能はStrix Cloudにはありませんので、手動で実施いただく必要があります。

なお、ルームサーバーの台数増減や設定変更などを行った場合にはサーバーインスタンスの再起動が必要になる場合があります。また、サーバーの負荷が高くなりすぎて動作が不安定になってしまった場合にも、サーバーインスタンスの再起動が必要になることがあります。それを避けるために、ルームサーバー数や秒間メッセージ数の上限をゲームタイトルに合わせて適切に設定してください。

STRIXのトークン認証とOAuth標準はどのような関係になっているのですか。

STRIXがサポートするOAuth client typeはpublicであり、native application profileに基づいています。また、authorization code grantの利用を想定しています (必要であれば、クライアントプログラムの設計により、client credentials grantなど他のgrantを利用することもできます)。

トークン認証を利用するためにはサーバー側に設定が必要です。Strix Cloudの場合には、アプリケーションダッシュボードの [オプション] 画面で [認証/認可] を有効にします。[ユーザーリソース取得API URL] には、resource serverの、「ユーザーの識別情報を提供するサービス」のエンドポイント (OpenID ConnectのUserInfo endpointのようなもの) のURLを指定します。protected resourceである識別情報の形式は (OpenID Connectのopenidスキーマのような) JSONオブジェクトであることを想定しており、その中には「ユーザーID」("sub" claimのようなもの) と「ユーザー名」("name" claimのようなもの) が含まれていることを前提としています。

実際のOAuthのフローは次のようになります。

(1) ゲームプログラムはプラットフォームの標準ウェブブラウザーを起動し、authorization serverのauthorization endpointにアクセスしてresource owner (プレイヤー) にauthorization codeを取得させます。
(2) ゲームプログラムは、このauthorization codeを受け取って、OAuth clientとしてauthorization serverのtoken endpointにアクセスしてaccess tokenを取得します。
(3) ゲームプログラムはaccess tokenをSDKに渡します。 (Strix Unity SDKの場合はStrixNetwor.instance.authorizationAccessToken に設定します。Strix Unreal SDKの場合はInitializeStrixNetworkWithHttpAccessToken関数の引数に指定します。) するとこのトークンは、サーバーとの接続処理の一環でSTRIXサーバーに転送されます。
(4) STRIXサーバーは、このトークンを用いてOAuth clientとしてresource serverにアクセスし、(OAuthから見た) protected resourceであるプレイヤーの識別情報を取得します。

以上でOAuthとしてのフローは終了ですが、その後STRIXサーバーはSTRIXとしてのクライアント認証トークンを発行し、それによってそれ以降のクライアント認証を行います。また、そのクライアント (プレイヤー) がルームに参加した際にresource serverから取得した識別情報の一部 (ユーザー名とユーザーID) を自動的にルームメンバープロパティに設定します。

ネットワークについて

サーバーの設定にある「最大秒間メッセージ数」と「最大メッセージサイズ」はどのような値ですか。

例として、50クライアントが参加しているルームでの同期のための通信のデータ量の計算は次のようになります。

各クライアントがメッセージを1個送信すると、サーバーからは50台のクライアントに向けて合計50個のメッセージが送信されます。50台のクライアントがそれぞれ1個ずつメッセージを送信した場合、サーバーは50個のメッセージを受け取り、延べ50 × 50 = 2500個のメッセージを送信します。この値に各クライアントが1秒間に送信するメッセージ数をかけることでサーバーの秒間メッセージ数が計算できます。これに1メッセージあたりのデータサイズをかけて、サーバーから送信する秒間データ量を「50 × 50 × 1クライアント当たりの秒間メッセージ数 × 1メッセージ当たりのデータサイズ」という式で見積もることができます。

これらのサーバーの設定は最大値を制限するものですから、これらの値を設定することにより、1秒あたりのデータ量に上限を設定することができます。

テキストチャットの実装を考えています。例えば、8人ルームで1人が発言した場合のメッセージはどうなりますか。

メッセージのサイズはメッセージの内容によって異なりますが、テキストチャットの場合にはおおよそチャットの文字列 (UTF-8) のバイト数 + ヘッダー (通常30~40バイト) 程度とお考えいただくといいでしょう。

通信料の対象になる通信はどの範囲でしょうか。StrixReplicatorなどの通信は含まれますか。

例えば、StrixReplicatorコンポーネントが行う複製やStrixMovementSynchronizerコンポーネントが行う移動同期の際にもメッセージの送受信が発生し、それらも料金を算定する際の通信量に含まれます。StrixMovementSynchronizerはSyncPeriodMinやSyncPeriodMaxによって指定した時間ごとにメッセージを送信するため、典型的なゲームでは、移動同期のメッセージの送受信による通信量が最も多くなります。

Strix Cloudはプロキシーを経由しても利用できますか。

ゲームクライアントからマスターサーバーやルームサーバーのインスタンスへのアクセスは、http/httpsのようなWebの通信プロトコルとは異なるプロトコルを使用しているため、一般的なhttp/https通信専用のプロキシーは使用できません。TCP接続を透過的に中継するような特殊なプロキシーが必要になります。ファイアーウォールを越えるアクセスは、プロキシーではなく、いわゆる「ポート開放」によって行うことをお勧めします。

なお、通信プロトコルとしてWSS (セキュアWebSocket) を選択した場合には、wss通信に対応した比較的新しいプロキシーであれば使用できる可能性があります。プロキシーの仕様をご確認ください。

Strix Cloudのサーバーインスタンスが使用するIPアドレスとポート番号を教えてください。

IPアドレスはサーバーインスタンスの起動時に動的に割り当てます。再起動の際に変わることもあります。Strix Cloudのサーバーインスタンスが使用するIPアドレスには決まった値がないとお考えください。

CCUとはどういう意味ですか。

Strix Cloudの場合には、これは特に、各サーバーインスタンスに接続しているクライアントの台数になります。

Strix Unity SDKについて

機能について

HTML5/WebGLプラットフォーム向けにビルドすることはできますか。

Strix Unity SDKのバージョン1.5.0から、HTML5/WebGLプラットフォーム向けのビルドに対応しました。なお、既存のSTRIXクライアントをWebGLプラットフォームで動作させるためには、サーバーの設定と一部スクリプトの変更が必要になります。詳しくはドキュメントをご覧ください。

ルームにフレンドを招待することはできますか。

リーダーであるプレイヤーがルームを作成し、独自に用意した (STRIX外の) ユーザー管理サーバーの機能を使ってフレンドを招待する場合を考えます。

作成したルームを一意に特定するための情報はルームのprimaryKeyプロパティになります。また、ルームサーバーに接続するためのアドレス情報 (IPアドレスとポート番号) も必要になります。リーダーはこれらの情報を取得してフレンドに通知します。フレンドは、これらの情報を用いてJoinRoomを呼び出し、ルームに参加することができます。

具体的には以下のようになります。

ルームのprimaryKeyプロパティは、ルーム作成後にStrixNetwork.instance.room.GetPrimaryKey()によって取得できます。
接続中のルームサーバーのアドレス情報はStrixNetwork.instance.roomSession.messageChannel.GetRemoteAddress()によって取得できます。
これらの情報を受け取ったフレンドはStrixNetworkのJoinRoomメソッドを使用してルームに参加できます。

ルームへの招待を受け取った際に、ルームの情報を見た上で招待を受けるかどうかを決められるようにしたいです。

プレイヤーに表示する情報はルームプロパティに格納されていると仮定します。
招待に含まれているアドレス情報を利用して指定されたルームサーバーに接続した後で、primaryKeyを利用してルーム情報を取得できます。

StrixNetwork.instance.roomSession.Connect()を使用すると、ルームに参加することなくルームサーバーに接続できます。
その後、StrixNetwork.instance.roomSession.roomClient.Get()でルームのprimaryKeyを指定すると、ルームプロパティを取得できます。

動的に生成したオブジェクトや変数を他者へ通知することは可能でしょうか。

事前に定義されているオブジェクト (プレハブGameObject) を動的にインスタンス化する場合、そのオブジェクトにあらかじめStrixReplicatorがアタッチされていれば自動的に複製が行われ、他のクライアント上でレプリカが自動的に生成されます。このときオブジェクトの同期対象プロパティの値も同期されます。レプリカが生成された時点で通常のオブジェクト初期化イベント (UnityのStartコールバックなど) が発生しますので、それによって他のクライアントで動的生成を契機とした処理を行うこともできます。

もしも同期対象になっていないオブジェクト (StrixReplicatorがアタッチされていないGameObject) の動的生成を他のクライアントで知りたいということであれば、残念ながらSTRIX自身にはそのような機能がありません。その場合は、RPCやメッセージリレーの機能を利用して、動的生成を行ったクライアントから他のクライアントへカスタム通知を行うことで実現可能です。

他プレイヤーが入退室したことを検知するコールバックはありますか。

StrixNetwork.instance.roomSession.roomClientにあるRoomJoinNotifiedが誰かがルームに参加したことの通知、RoomLeaveNotifiedが誰かがルームから退出したことの通知です。

ルームオーナーが変わったことを契機に処理を行うことはできますか。

Strix Unity SDKにはルームオーナーの変更を通知するイベントがあります。StrixNetwork.instance.roomSession.roomClient.RoomOwnerChangedイベントです。このイベントハンドラーで必要な処理を行うことができます。

イベントハンドラーを使用せず、Updateやコルーチンの途中でオーナー変更の有無を知りたい場合には、以前のルームオーナーを覚えておき、現在のルームオーナーと以前のルームオーナーを比較することで判定できます。StrixNetwork.instance.room.GetOwnerUid()によって現在のルームオーナーを表すUIDを取得し、以前のルームオーナーのUIDと比較します。なお、UIDはインターフェイスなので、UIDを比較する際には、== 演算子ではなく、Equalsメソッドを使用してStrixNetwork.instance.room.GetOwnerUid().Equals(previousRoomOwnerUid)のように比較してください。

STRIXにはユーザー識別(IDやName)のサポートがありますか。

クライアントでユーザー認証を行っていることを前提に、ユーザーの識別のみを行う場合は、ルームメンバープロパティの"name"にユーザーの識別子を設定します。プレイヤーに見せる「ユーザー名」と、プログラムが内部で意識する「ユーザーID」を区別している場合には、「ユーザー名」を"name"に格納し、「ユーザーID」はカスタムプロパティを定義して格納することが一般的です。この場合のカスタムプロパティ名としては通常"userId"を使用します。

サーバー側で確実に認証されたユーザー情報を取得したい場合にはトークン認証を利用できます。外部に用意した認証サーバーが認証トークンを発行し、それをクライアントからSTRIXサーバーに通知し、STRIXサーバーが認証サーバーからユーザー名やユーザーIDを取得します。この場合、ルームメンバープロパティ"name"とルームメンバーのカスタムプロパティ"userId"にはSTRIXサーバーが認証サーバーから取得したユーザー名とユーザーIDが自動的に設定されます。

トークン認証についての詳細は、Strix Unity SDKユーザーズガイドを参照してください。Strix Cloudでサーバーにトークン認証を行わせるための設定方法はStrix Cloudユーザーズガイドを参照してください。

ルームに参加した後で通信切断があった場合、それを検出する方法はありますか。

Strix Unity SDKではStrixNetwork.instance.roomSessionClosedイベントを利用できます。このイベントはルームサーバー接続が閉じられたときに発生するイベントですが、通信切断の検出にも使用できます。

ルームオーナーのみにRPCを送ることはできますか。

このメソッドを使用すると、RPCの対象のGameObjectのオーナー (オリジナルのGameObjectをインスタンス化したクライアント) に関係なく、ルームオーナーのGameObjectでのみRPCが実行されます。

マスターサーバー全体にメッセージを同報したいのですがどうすればいいですか。

Strix Unity SDKの場合、自分と同じルームに参加していないクライアントにメッセージを送るためには、他のサーバーを用意する必要があります。例えばStrix Messengerサーバーを利用すれば、ルームとは関係なくメッセージを送ることができ、大量のクライアントへメッセージを同報するような使い方にも対応しています。

ルーム内で数人のプレイヤーをグループ化しておき、グループ内のみで情報の送受信をすることはできますか。

ただし、指定した1人のプレイヤーに向けてRPCを呼び出すことが可能ですので、各グループ内の人数が少なければ、クライアント側でグループのメンバーを管理しておき、メンバー1人ずつに向けて繰り返しRPCを呼ぶことで同様の機能を実現することが可能です。

LeaveRoomを呼ぶ際に特定のGameObjectが破壊されないようにすることはできますか。

GameObjectのオーナーがLeaveRoomを呼ぶなどしてルームから退出した場合、通常、オリジナルのGameObjectもそのレプリカも全て破壊されます。しかしこの動作は、StrixReplicatorにあるsyncDestroyというフィールドによって変更できます。

特定のGameObjectでのみStrixReplicatorのsyncDestroyフィールドをfalseに設定することにより、LeaveRoom時の、そのGameObjectの破壊処理をスキップさせることができます。
例えば、エディターでプレハブを作成する際にsyncDestroyをfalseに設定しておくと、そのプレハブからインスタンス化したオリジナルのGameObjectも、それの全てのレプリカも、破壊されなくなります。

モバイルゲームがバックグラウンドになると何が起きますか。特にルームオーナーはどうなるのですか。

以下、詳細を説明します。

(バックグラウンドになった際の動作)

STRIXを利用するモバイルアプリがバックグラウンドになったときには、基本的にはサーバーとの通信が切断されます。実際の切断までの時間は、OSやバージョン、Androidの場合はメーカーや機種によっても異なりますが、最短で1秒以内、最長で2分間程度になります。切断までの時間が長い状況では、切断以前に再びアプリがアクティブになれば、切断は免れてそのまま動作を継続します。

ルームに参加している間にバックグラウンドになりサーバーとの通信が切断されると、STRIXではルームから退出したものとして扱われます。他のクライアントでは、通常は切断された時点でレプリカが全て削除されます。また、自デバイスでは、復帰した (アクティブになった) 後でルーム退出などのイベントが処理されることになります。

(ルームオーナーがバックグラウンドになった場合)

ルームオーナーがバックグラウンドになると、ルームオーナーの通信が切断されるため、退出扱いになります。

サーバーの設定に「ルームオーナー移譲」の項目があります。これが無効になっていると、ルームオーナーの退出とともにルームが削除され、他のルームメンバーは全員強制退出になります。「ルームオーナー移譲」を有効にしておくと、ルームオーナーが退出した際に自動的に他のクライアント (プレイヤー) にルームオーナーが移譲され、他のメンバーはプレイを継続できます。なお、移譲先のクライアントはルームサーバーが選択します。ランダムとお考えください。

モバイルゲームがバックグラウンドになった際のルーム退出までの時間を短くできませんか。

STRIXを利用するモバイルアプリがバックグラウンドになったときには、基本的にはサーバーとの通信が切断され、ルームから退出します。実際の切断までの時間は、OSやバージョン、Androidの場合はメーカーや機種によっても異なりますが、最短で1秒以内、最長で2分間程度になります。

UnityにはOnApplicationPauseというコールバックがあり、モバイルアプリがバックグラウンドに移行する際やアクティブに復帰する際に呼び出されます。これを利用して退出までの待ち時間を短くすることができます。バックグラウンドに移行する際にLeaveRoomを呼ぶことで、バックグラウンドによる通信切断を待たずにルームから退出させます。

また、バックグラウンドからアクティブに復帰した際には、そのクライアントはルームから退出した状態になっており、レプリカも削除されています。そのままプレイを続行することはできません。以前と同じルームに参加し直したり、他の適切な画面 (タイトル画面など) へ遷移したりといった処理を行う必要があります。

なお、UnityのOnApplicationPauseは、引数によってバックグラウンドに移行するのか復帰するのかを判別します。詳しくはUnityのドキュメントを参照してください。

変数同期はRPCよりも通信量が多いのですか。どの程度違うのですか。

変数同期を使用する場合、決まった頻度 (sendRateプロパティで指定された頻度) で同期処理が行われます。しかし、同期処理のたびに必ず変数の値を送信するわけではなく、値が変更された変数のみを送信するようになっています。このため、変数同期でもRPCでも、状態に変化があった場合のみ情報を送信するという動作になり、通信量という点では大きな差は生じません。

ユーザーズガイドの「パフォーマンスを向上させる方法」に、変数同期よりもRPCの方が性能が良いと記載してありますが、これは通信量に注目したものではなくSDK内部の処理性能を考慮したものです。

変数同期の場合には、変数の値が変更されたことの検出にある程度のオーバーヘッドが生じます。オーバーヘッドと言っても通常は問題になるような処理ではありませんが、同期対象の変数が大量にあって、その大半がめったに変化しないような場合には無視できなくなる場合があります。同期対象の変数を減らした上で、ユーザー入力などの延長でそのままRPCを呼び出すように書き直すことにより、処理を軽くできる可能性があります。

StrixMovementSynchronizerの同期頻度のパラメーターは動的に変更できますか。

ただし、Strix Unity SDKでは、StrixMovementSynchronizerのプロパティ値の変更は自動的に同期されません。プロパティの値を変更する場合は、オーナー (オリジナルのオブジェクト) のみでなく、レプリカでも同時にプロパティの値を変更する必要があります。

ゲームのメンテナンス中を知らせる画面を出すことはできますか。

全サーバー (マスターサーバー/ルームサーバー) を停止すれば、新たにログインできなくなり接続処理がエラーになります。マスターサーバーへの接続エラーを契機として「メンテナンス画面」を表示することはできますが、他の理由によるエラー (例えば、一時的に通信状況が悪かったために接続できず、再試行すれば接続できる可能性が高い場合) との区別は難しいかもしれません。

また、やはり全サーバーを停止すればプレイ中の全プレイヤーが切断されますが、これも他の理由による切断との区別が難しく、またゲーム内容によっては「突然の切断」は望ましくないかもしれません。

このため、STRIXサーバーの機能のみを利用したメンテナンスの実施は難しいと言わざるを得ません。

家庭用ゲーム機向けのゲームを開発できますか。

ただし、家庭用ゲーム機用のゲームタイトルを開発するためには専用の開発環境が必要になります。この開発環境はStrix Unity SDKには含まれていません。各プラットフォームから別途入手していただく必要があります。

Strix Unity SDKはどのバージョンのUnityをサポートしていますか。

エラーや他の問題について

StrixNetworkManagerに関して「Some objects were not cleaned up when closing the scene.」というエラーが発生します。

Unityはプレイ終了時にシーン内のGameObjectを破壊しますが、その処理が終わった後に破壊されなかったGameObjectが残っているとこのエラーが発生します。一般に、OnDestroyの処理中に新しくGameObjectをインスタンス化してしまうことによって起きることが多いようです。

メッセージの全体は次のようなものです:

Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?) The following scene GameObjects were found:
StrixNetworkManager

StrixNetworkManagerはStrix Unity SDKが内部で使用するGameObjectです。C#スクリプトがStrixNetworkのシングルトンインスタンス (StrixNetwork.instance) を参照する際にStrixNetworkManagerもインスタンス化されます。通常は、プレイ終了時にStrixNetworkのシングルトンインスタンスと一緒にStrixNetworkManagerも破壊されます。

エラーメッセージの末尾にStrixNetworkManagerが含まれている場合、問題のエラーは、OnDestroy()のようなプレイ終了時に実行されるコールバック内で、StrixNetworkとStrixNetworkManagerのインスタンスが破壊された後でStrixNetwork.instanceにアクセスしているために発生しているものと思われます。OnDestroy()の中ではStrixNetworkを参照しないようにするか、StrixNetwork.isInitialized (これは、StrixNetworkのシングルトンインスタンスが存在するときにtrueになり、Destroyされるとfalseになります) をチェックした上で、値がtrueのときにのみSTRIX関連の後処理を行うようにすることで、このエラーを回避できます。

通信エラーによるリレーメッセージの再送などは、ゲーム側でどの程度対応する必要があるでしょうか。

単純なオブジェクトの移動同期でカクつき(移動が一瞬停止する)現象が生じる場合があります。

StrixMovementSynchronizerのMaxSpeedに設定する速度は1秒当たりの移動距離です。MaxSpeedには当該GameObjectの最大移動速度を設定してください。

なお、移動同期のパラメーターの調整については、ユーザーズガイドのハウツーもご覧ください。

特定のルームプロパティに値を設定し、後で参照すると、設定した値が取得できません。

a) ルームプロパティの値を更新するためには、SetRoomメソッドを呼び出す必要があります。Strix Unity SDKが提供するクラスに値を設定するのみでは、ルームサーバーが保持しているルームプロパティの値は変更されません。特にStrixNetwork.instance.roomにあるSetName()等のメソッドを呼び出しても変更されません。

b) SetRoomメソッドを呼び出すことができるのはルームオーナーのみです。他のクライアント (プレイヤー) が呼び出すとエラーになり (失敗ハンドラーが起動され)、値は変更されません。

c) ルームプロパティの値を設定したり参照したりする際に、ルームプロパティの名前を文字列で指定する場合があります (例えば、IDictionary<string, object>型でルームプロパティの集合を表す場合が該当します)。このとき、プロパティの名前の文字列が間違っていても、エラーになりません (指定した通りの名前のカスタムプロパティとして扱われます)。プロパティの名前を正しく記載しているかどうか、以下の点に注意して再確認してみてください。

  • プロパティ名では大文字と小文字を区別します。またスペース文字の有無も区別します。大文字小文字の使い分けなどが正しいかどうか確認してください。(なお、STRIXが定義しているルームプロパティの名前は全て、先頭が英小文字です。)

d) ルームプロパティにはデータ型があります。使用するAPIによっては任意の型の値を受け付けるものがありますが、誤ったデータ型としてルームプロパティにアクセスした場合、エラー等は発生しませんが、正しくアクセスできません。

  • 標準のプロパティに値を設定する際に正しいデータ型の値を指定しているかどうかどうか確認してください。
  • 標準のプロパティの値を参照する際に正しいデータ型を使用しているかどうか確認してください。
  • カスタムプロパティにアクセスする際には、値の設定と参照の際のデータ型が一貫していることを確認してください。

JoinRoomメソッドの成功ハンドラーも失敗ハンドラーも呼ばれず処理が先に進みません。

マスターサーバーに接続した後で、SearchRoom等のメソッドによってルームの検索を行い、見つかったルームに参加するためにJoinRoomを呼ぶ際に、JoinRoomの引数としてルームサーバーではなくマスターサーバーのアドレス (ホスト名やIPアドレス、およびポート番号) を指定してしまうと、JoinRoomが無応答になる場合があります。(実際には、約30秒後にタイムアウトして失敗ハンドラーが起動されます。)

アバターの着せ替え機能を実装するためにRPCでメッシュを送ろうとしていますがうまく動作しません。

IDを伝達する方法はいくつか考えられますが、プレイヤーのアバターの外観ということであれば、ルームメンバープロパティを使う方法をお勧めします。適当なカスタムプロパティ (例えば"avatarId") を定義し、そのプロパティ値にIDを設定します。レプリカ側では、レプリカの生成時と、プロパティの変更イベントを契機にメッシュの切り替えを行うことができます。

Strix Unreal SDKについて

機能について

ルームにフレンドを招待することはできますか。

リーダーであるプレイヤーがルームを作成し、独自に用意した (STRIX外の) ユーザー管理サーバーの機能を使ってフレンドを招待する場合を考えます。

作成したルームを一意に特定するための情報はルームのprimaryKeyプロパティになります。また、ルームサーバーに接続するためのアドレス情報 (IPアドレスとポート番号) も必要になります。リーダーはこれらの情報を取得してフレンドに通知します。フレンドは、これらの情報を用いてJoin Room関数を呼び出し、ルームに参加することができます。

具体的には以下のようになります。

ルームのprimaryKeyプロパティは、ルーム作成後にGet Current Room関数を呼び出してStrix Room構造体を取得し、そのIdプロパティから取得できます。接続中のルームサーバーのアドレス情報としては、Create Roomを呼び出す際に接続したルームサーバーのアドレス情報を通知します。これらの情報を受け取ったフレンドは、Connect To Room Server関数にアドレス情報を渡してルームサーバーに接続し、その後Join Room関数でルームIDを指定してルームに参加できます。

なお、Strix Unreal SDKユーザーズガイドのハウツーに関連する情報を記載していますので、併せてご参照ください。

ルームへの招待を受け取った際に、ルームの情報を見た上で招待を受けるかどうかを決められるようにしたいです。

プレイヤーに表示する情報はルームプロパティに格納されていると仮定します。
招待に含まれているアドレス情報を利用して指定されたルームサーバーに接続した後で、指定されたprimaryKeyを持つルームを検索することでルーム情報を取得できます。ただし、primaryKeyを指定したルーム検索にはC++コードが必要になります。
詳しくはStrix Unreal SDKユーザーズガイドのハウツーを参照してください。

動的に生成したオブジェクトや変数を他者へ通知することは可能でしょうか。

事前に定義されているオブジェクト (アクター) を動的にスポーンする場合、そのオブジェクトにあらかじめStrix Replicatorがアタッチされていれば自動的に複製が行われ、他のクライアント上でレプリカが自動的に生成されます。このときオブジェクトの同期対象プロパティの値も同期されます。レプリカが生成された時点でUnreal Engineの通常のオブジェクト初期化イベント (イベントBegin Playなど) やSTRIXの同期イベント (On Sync Beginなど) が発生しますので、それによって他のクライアントで動的生成を契機とした処理を行うこともできます。

もしも同期対象になっていないオブジェクト (Strix Replicatorがアタッチされていないアクター) の動的生成を他のクライアントで知りたいということであれば、残念ながらSTRIX自身にはそのような機能がありません。その場合は、RPCやメッセージリレーの機能を利用して、動的生成を行ったクライアントから他のクライアントへカスタム通知を行うことで実現可能です。

他プレイヤーが入退室したことを検知するコールバックはありますか。

Strix Notification ListenerコンポーネントにStrix Room Join Notification ArrivedとStrix Room Leave Notification Arrivedというイベントがあります。Strix Room Join Notification Arrivedは誰かがルームに参加したことの通知、Strix Room Leave Notification Arrivedは誰かがルームから退出したことの通知です。

ルームオーナーが変わったことを契機に処理を行うことはできますか。

Strix Unreal SDKにはルームオーナーの変更を通知するイベントがあります。Strix Notification ListenerコンポーネントのStrix Room Owner Changedイベントです。このイベントハンドラーで必要な処理を行うことができます。

STRIXにはユーザー識別(IDやName)のサポートがありますか。

クライアントでユーザー認証を行っていることを前提に、ユーザーの識別のみを行う場合は、ルームメンバープロパティの"name"にユーザーの識別子を設定します。プレイヤーに見せる「ユーザー名」と、プログラムが内部で意識する「ユーザーID」を区別している場合には、「ユーザー名」を"name"に格納し、「ユーザーID」はカスタムプロパティを定義して格納することが一般的です。この場合のカスタムプロパティ名としては通常"userId"を使用します。

サーバー側で確実に認証されたユーザー情報を取得したい場合にはトークン認証を利用できます。外部に用意した認証サーバーが認証トークンを発行し、それをクライアントからSTRIXサーバーに通知し、STRIXサーバーが認証サーバーからユーザー名やユーザーIDを取得します。この場合、ルームメンバープロパティ"name"とルームメンバーのカスタムプロパティ"userId"にはSTRIXサーバーが認証サーバーから取得したユーザー名とユーザーIDが自動的に設定されます。

トークン認証についての詳細は、Strix Unreal SDKユーザーズガイドを参照してください。Strix Cloudでサーバーにトークン認証を行わせるための設定方法はStrix Cloudユーザーズガイドを参照してください。

ルームに参加した後で通信切断があった場合、それを検出する方法はありますか。

Strix Notification ListenerのRoom Context Closedイベントを利用できます。
このイベントはルームが削除されたとき、プレイヤーが退出したとき、キックされたときなどに実行されますが、通信切断の場合にも実行されます。

ルームオーナーのみにRPCを送ることはできますか。

この関数を使用すると、RPCの対象のアクターのオーナー (オリジナルのアクターをスポーンしたクライアント) に関係なく、ルームオーナーのアクターでのみRPCが実行されます。

マスターサーバー全体にメッセージを同報したいのですがどうすればいいですか。

Strix Unreal SDKでは、チャネル機能を使用して同時に複数のルームに参加することができますので、オンライン中に全員が必ず入室するルームを作成し、そのルームにいるメンバー全員にRPCを送るといった方法が考えられます。この場合、そのルームの最大人数 (capacity) が同時接続数を制限することになりますのでご注意ください。

STRIXのゲームサーバーとは別にサーバーを用意してメッセージを送ることもできるでしょう。例えばStrix Messengerサーバーを利用すれば、ルームとは関係なくメッセージを送ることができ、大量のクライアントへメッセージを同報するような使い方にも対応しています。

ルーム内で数人のプレイヤーをグループ化しておき、グループ内のみで情報の送受信をすることはできますか。

ただし、指定した1人のプレイヤーに向けてRPCを呼び出すことが可能ですので、各グループ内の人数が少なければ、クライアント側でグループのメンバーを管理しておき、メンバー1人ずつに向けて繰り返しRPCを呼ぶことで同様の機能を実現することが可能です。

LeaveRoomを呼ぶ際にGameObjectが破壊されないようにすることはできますか。

アクターのオーナーがLeave Roomを呼ぶなどしてルームから退出した場合、通常、オリジナルのアクターもそのレプリカも全て破壊されます。しかしこの動作は、Strix ReplicatorにあるShould Receive Destroy Eventsというプロパティによって変更できます。

特定のアクターでのみStrix ReplicatorのShould Receive Destroy Eventsプロパティをfalseに設定することにより、Leave Room時の、そのアクターの破壊処理をスキップさせることができます。
例えば、エディターでアクターのクラスを定義する際にShould Receive Destroy Eventsプロパティをfalseに設定しておくと、そのクラスをスポーンしたオリジナルのアクターも、それの全てのレプリカも、破壊されなくなります。

C++からStrix Unreal SDKを使用することはできますか。

Strix Unreal SDKのBlueprint向け関数は、UStrixBlueprintFunctionLibraryクラスで定義されています。これらの関数を、一般的なBlueprint関数の呼び出し方にしたがってC++コードから呼び出すことができます。また、大半のBlueprint関数には、UStrixNetworkFacadeクラス内に対応するC++ APIが定義されています。そちらの関数を呼び出していただくこともできます。

また、C++コードを用いてカスタムメッセージを定義し、メッセージリレーAPIを用いて送受信することも可能です。具体的な方法はStrix Unreal SDKユーザーズガイドのリレーメッセージの節をご参照ください。

モバイルゲームがバックグラウンドになると何が起きますか。特にルームオーナーはどうなるのですか。

以下、詳細を説明します。

(バックグラウンドになった際の動作)

STRIXを利用するモバイルアプリがバックグラウンドになったときには、基本的にはサーバーとの通信が切断されます。実際の切断までの時間は、OSやバージョン、Androidの場合はメーカーや機種によっても異なりますが、最短で1秒以内、最長で2分間程度になります。切断までの時間が長い状況では、切断以前に再びアプリがアクティブになれば、切断は免れてそのまま動作を継続します。

ルームに参加している間にバックグラウンドになりサーバーとの通信が切断されると、STRIXではルームから退出したものとして扱われます。他のクライアントでは、通常は切断された時点でレプリカが全て削除されます。また、自デバイスでは、復帰した (アクティブになった) 後でルーム退出などのイベントが処理されることになります。

(ルームオーナーがバックグラウンドになった場合)

ルームオーナーがバックグラウンドになると、ルームオーナーの通信が切断されるため、退出扱いになります。

サーバーの設定に「ルームオーナー移譲」の項目があります。これが無効になっていると、ルームオーナーの退出とともにルームが削除され、他のルームメンバーは全員強制退出になります。「ルームオーナー移譲」を有効にしておくと、ルームオーナーが退出した際に自動的に他のクライアント (プレイヤー) にルームオーナーが移譲され、他のメンバーはプレイを継続できます。なお、移譲先のクライアントはルームサーバーが選択します。ランダムとお考えください。

モバイルゲームがバックグラウンドになった際のルーム退出までの時間を短くできませんか。

STRIXを利用するモバイルアプリがバックグラウンドになったときには、基本的にはサーバーとの通信が切断され、ルームから退出します。実際の切断までの時間は、OSやバージョン、Androidの場合はメーカーや機種によっても異なりますが、最短で1秒以内、最長で2分間程度になります。

Unreal EngineにはPlatform Game Instanceというクラスがあり、このクラス (またはその派生クラス) をゲームインスタンスとして使用することにより、バックグラウンドへの移行や復帰を検出できます。バックグラウンドへの移行の際にはApplication Will Enter Background Delegateが、復帰の際にはApplication Has Entered Foreground Delegateが、それぞれ実行されます。

Application Will Enter Background Delegateを利用して、退出までの待ち時間を短くできます。バックグラウンドに移行する際にLeave Roomを呼ぶことで、バックグラウンドによる通信切断を待たずにルームから退出させます。

また、バックグラウンドからアクティブに復帰した際には、そのクライアントはルームから退出した状態になっており、レプリカも削除されています。そのままプレイを続行することはできません。Application Has Entered Foreground Delegateを利用して、以前と同じルームに参加し直したり、他の適切な画面 (タイトル画面など) へ遷移したりといった処理を行う必要があります。

Platform Game Instanceに関して詳しくはUnreal Engineのドキュメントを参照してください。

変数同期はRPCよりも通信量が多いのですか。どの程度違うのですか。

変数同期を使用する場合、決まった頻度 (Ticks Per Secondプロパティで指定された頻度) で同期処理が行われます。しかし、同期処理のたびに必ず変数の値を送信するわけではなく、値が変更された変数のみを送信するようになっています。このため、変数同期でもRPCでも、状態に変化があった場合のみ情報を送信するという動作になり、通信量という点では大きな差は生じません。

ユーザーズガイドの「パフォーマンスを向上させる方法」に、変数同期よりもRPCの方が性能が良いと記載してありますが、これは通信量に注目したものではなくSDK内部の処理性能を考慮したものです。

変数同期の場合には、変数の値が変更されたことの検出にある程度のオーバーヘッドが生じます。オーバーヘッドと言っても通常は問題になるような処理ではありませんが、同期対象の変数が大量にあって、その大半がめったに変化しないような場合には無視できなくなる場合があります。同期対象の変数を減らした上で、ユーザー入力などの延長でそのままRPCを呼び出すように書き直すことにより、処理を軽くできる可能性があります。

Strix Movement Synchronizerの同期頻度のパラメーターは動的に変更できますか。

Strix Unreal SDKでは、Strix Movement Synchronizerのプロパティは同期されており、オーナー (オリジナルのアクター) のStrix Movement Synchronizerのプロパティの値を変更すると、レプリカのプロパティも変更されます。逆にレプリカ側でプロパティの値を変更してもオーナーへは反映されません。プロパティの変更は常にオーナー側で行うようにしてください。

ゲームのメンテナンス中を知らせる画面を出すことはできますか。

全サーバー (マスターサーバー/ルームサーバー) を停止すれば、新たにログインできなくなり接続処理がエラーになります。マスターサーバーへの接続エラーを契機として「メンテナンス画面」を表示することはできますが、他の理由によるエラー (例えば、一時的に通信状況が悪かったために接続できず、再試行すれば接続できる可能性が高い場合) との区別は難しいかもしれません。

また、やはり全サーバーを停止すればプレイ中の全プレイヤーが切断されますが、これも他の理由による切断との区別が難しく、またゲーム内容によっては「突然の切断」は望ましくないかもしれません。

このため、STRIXサーバーの機能のみを利用したメンテナンスの実施は難しいと言わざるを得ません。

家庭用ゲーム機向けのゲームを開発できますか。

ただし、家庭用ゲーム機用のゲームタイトルを開発するためには専用の開発環境が必要になります。この開発環境はStrix Unreal SDKには含まれていません。各プラットフォームから別途入手していただく必要があります。

また、プラットフォームが提供する開発環境に加えて、弊社が提供する、家庭用ゲーム機専用のSTRIXのライブラリーも必要になります。しかし、このライブラリーはStrix CloudのサイトからダウンロードいただけるStrix Unreal SDKには含まれていません。こちらの入手方法に関しましては、弊社のSTRIXサポートチームまでお問い合わせください。

Strix Unreal SDKはどのバージョンのUnreal Engineをサポートしていますか。

エラーや他の問題について

Disconnect Master Server関数を呼んでいないのにIs Master Server Connected関数がfalseを返します。

これは正常な動作です。

マスターサーバーとの接続は一定時間リクエストが無いと自動的に切断され、次にリクエストを送る際に自動的に再接続されるようになっています。Is Master Server Connected関数は、Disconnect Master Serverで積極的に切断した場合の他に、この自動切断されているときにもfalseを返します。

この自動的な切断と再接続の処理は、マスターサーバーと通信する関数の機能に影響しません。マスターサーバーの機能を利用する前にIs Master Server Connectedで接続状況を確認する必要はありません。

2回目にルームに参加しようとするとエラーになります。

ゲームプログラムを起動した後、最初は、ルームに参加し、ゲームをプレイし、ルームから退出するという一連の処理が正常に動作するのに、その後、もう一度ルームに参加しようとすると「Room connection with id N already exists」(Nは数値) というエラーが出て参加できないという現象が起きることがあります。これは、ルームサーバーに接続しようとしているがそのチャネルは既にルームサーバーに接続中である、という状況で発生します。

Leave Room関数はルームから退出するという処理のみを行います。1回目のゲームプレイが終わりLeave Room関数によって退出した後も、Strix Unreal SDKの内部ではルームサーバーとの接続を維持しています。そのまま、2回目のルームへ参加しようとしてConnect To Room Serverを呼ぶと当該エラーが発生します。(明示的にConnect To Room Serverを呼ぶのではなくNodeRoom系の関数を使用している場合も、内部的にルームサーバーへの接続処理を行おうとして、同じエラーになる場合があります。)

通信エラーによるリレーメッセージの再送などは、ゲーム側でどの程度対応する必要があるでしょうか。

単純なオブジェクトの移動同期でカクつき(移動が一瞬停止する)現象が生じる場合があります。

Strix Movement SynchronizerのMax Speedに設定する速度は1秒当たりの移動距離です。Max Speedには当該アクターの最大移動速度を設定してください。

なお、移動同期のパラメーターの調整については、ユーザーズガイドのハウツーもご覧ください。

C++クラスからUStrixReplicatorComponentのIsReplicatingフラグを参照すると常にfalseになってしまいます。

UStrixReplicatorComponent::IsReplicatingというメンバー変数はブループリント用で、別にゲッター関数が定義されています。C++から参照する場合には、ゲッターであるUStrixReplicatorComponent::GetIsReplicating()関数を呼び出してください。

特定のルームプロパティに値を設定し、後で参照すると、設定した値が取得できません。

a) ルームプロパティの値を更新するためには、Set Room関数を呼び出す必要があります。Strix Unreal SDKが提供する構造体に値を設定するのみでは、ルームサーバーが保持しているルームプロパティの値は変更されません。

b) Set Room関数を呼び出すことができるのはルームオーナーのみです。他のクライアント (プレイヤー) が呼び出すとエラーになり (失敗コールバックが実行され)、値は変更されません。

c) ルームプロパティの値を設定したり参照したりする際に、ルームプロパティの名前を文字列で指定する場合があります (例えば、Strix Property Map構造体を使用する場合が該当します)。このとき、プロパティの名前の文字列が間違っていても、エラーになりません (指定した通りの名前のカスタムプロパティとして扱われます)。プロパティの名前を正しく記載しているかどうか、以下の点に注意して再確認してみてください。

  • プロパティ名では大文字と小文字を区別します。またスペース文字の有無も区別します。大文字小文字の使い分けなどが正しいかどうか確認してください。(なお、STRIXが定義しているルームプロパティの名前は全て、先頭が英小文字です。)
  • Strix Unreal SDKの場合、標準のプロパティを構造体のメンバーとしてアクセスできる場合がありますが、その変数名はプロパティの名前を文字列で表す際の名前とは異なっています。例えば、ルームの名前を表すルームプロパティは、Strix Room構造体ではNameという名前ですが、文字列で表す場合は"name"です。

d) ルームプロパティにはデータ型があります。使用するAPIによっては任意の型の値を受け付けるものがありますが、誤ったデータ型としてルームプロパティにアクセスした場合、エラー等は発生しませんが、正しくアクセスできません。

  • 標準のプロパティに値を設定する際に正しいデータ型の値を指定しているかどうかどうか確認してください。
  • 標準のプロパティの値を参照する際に正しいデータ型を使用しているかどうか確認してください。
  • カスタムプロパティにアクセスする際には、値の設定と参照の際のデータ型が一貫していることを確認してください。

Join Room関数の成功コールバックも失敗コールバックも呼ばれず処理が先に進みません。

マスターサーバーに接続した後で、ルームサーバーに接続するためにConnect To Room Serverを呼び出す際に、ルームサーバーではなくマスターサーバーのアドレス (ホスト名やIPアドレス、およびポート番号) を指定してしまうと、成功コールバックが実行されて接続に成功したように見えますが、その後のルームサーバーの機能を利用するAPIが無応答になる場合があります。(実際には、約30秒後にタイムアウトして失敗コールバックが実行されます。)

アバターの着せ替え機能を実装するためにRPCでメッシュを送ろうとしていますがうまく動作しません。

IDを伝達する方法はいくつか考えられますが、プレイヤーのアバターの外観ということであれば、ルームメンバープロパティを使う方法をお勧めします。適当なカスタムプロパティ (例えば"avatarId") を定義し、そのプロパティ値にIDを設定します。レプリカ側では、レプリカの生成時と、プロパティの変更イベントを契機にメッシュの切り替えを行うことができます。

「Plugin 'StrixSDK' failed to load because module 'StrixSDK' could not be found.」というエラーが出ます。

この現象が発生した場合、次の手順に従ってプロジェクトに (中身のない) C++クラスを追加することで回避できます。

1. コンテンツブラウザで [新規追加] から [新規C++クラス] を選びます。
2. [親クラスを選択] に対して [なし] を選択して [次へ] をクリックします。
3. [新規なしに名前を付ける] の [ファイル名] にプロジェクトで使用しない名前 (例えばMyUnusedClass) を入力して [クラスを作成] をクリックします (名前以外は変更不要です)。
4. C++のコンパイルが始まりますので、しばらく待ちます。
5. Visual StudioのIDEが起動しますので、C++ソースファイル (MyUnusedClass.cpp) が開かれるまで待ち、その後 (何も編集せずに) Visual Studioを閉じます。
6. Unreal Engineのエディターも一旦終了します。
7. 再度Unreal Engineのエディターを起動してプロジェクトを開き、パッケージを作成します。

この手順を一度行えば、ご質問のエラーは起きなくなります。