キャッシュイベント
Photonのイベントはゲームロジック上、またはルーム内のプレイヤー同士が通信するうえで中心的な役割を果たします。
クライアントはOpRaiseEvent
を呼んで、ルーム内の1人または複数のプレイヤーにデータを送信します。
参加中のプレイヤーは全員、これらのイベントをただちに受信することが可能です。
ただし、キャッシュオプションを使わない限り、後から参加したプレイヤーはこれらのイベントを受信できません。
イベントをキャッシュする際、Photon Serverはイベントをルームステート内に保存し、後から参加するプレイヤーもそのイベントを利用できるようにします。
そしてPhoton Serverは結果として発生する「ライブ」イベントを送信するよりも前に、参加したプレイヤーにまず上記のイベントを送信します。
使用例1:
ラウンド作成のタイムスタンプをデータとして含む「start time」イベントをキャッシュできます。
これによってゲームに参加するプレイヤーは全員、ラウンドがいつ開始したのかを知ることができます(また、いつ終了するのかについても同様です)。
順番どおりの送信を保証
参加するプレイヤーは、イベントがサーバーに到達したのと同じ順番で、キャッシュイベントを取得します。
クライアントはまずルームとプレイヤープロパティを読み(各プレイヤーを認識するため)、その後キャッシュイベントを取得します。
その後、参加後に送信されたすべてのイベントが配信されます。
つまり、キャッシュイベントを受信する順番は、それらのイベントが送信された順番と同一とみなして問題ありません。
ただしUDPが使用された場合や、イベントが低信頼性で送信された場合に例外が発生します。
イベントのキャッシュ方法
詳細へと進む前に、イベントのキャッシュ方法を理解しましょう:
それぞれのキャッシュイベントは、コード、データ、送信者のアクター番号によって定義されます。
イベントキャッシュは、2つの「論理パーティション」に分類できます:
- 「グローバルキャッシュ」: ルームに関連するキャッシュ (ActorNr == 0)。
これには、EventCaching.AddToRoomCacheGlobal
フラグとともに送信され、明示的に削除されていないすべてのキャッシュイベントが含まれます。 これらのキャッシュイベントは、元の送信者までさかのぼることはできません。
このため、これらのイベントは参加中のすべてのアクターに送信されます。 - 「アクターキャッシュ」: 特定のアクター番号に関連するキャッシュ (ActorNr != 0)。
これには、そのアクターによって送信され、明示的にグローバルキャッシュに追加されていない、またはグローバルキャッシュから削除されていないすべてのキャッシュイベントが含まれます。
これらのイベントは元来の送信者を除く、参加中のすべてのアクターに送信されます。
イベントキャッシュを管理
LoadBalancing APIとPUNでは、ユーザーはRaiseEventOptions
オブジェクトをすべての OpRaiseEvent
コールに渡す必要があります。
このパラメータはCachingOption
プロパティを含みます。
想定されるそれぞれのEventCaching
値が、イベントキャッシュにどのような影響を与えるかみてみましょう:
DoNotCache
: デフォルト値です。送信するイベントがルームのキャッシュに追加されないことを示しています。AddToRoomCache
: 送信するイベントが送信アクターのルームキャッシュに追加されることを示しています。
送信アクターの番号でマークされます。AddToRoomCacheGlobal
: 送信するイベントが「グローバルキャッシュ」に追加されることを意味しています。
この値を使用する場合には留意してください。このコードをで削除を明示的にリクエストすると、イベントは削除のみされます。その他の場合には、イベントのライフタイムはルームと同一になります。RemoveFromRoomCache
: 指定した「フィルタパターン」に合致する、以前取得したキャッシュイベントすべてがキャッシュから削除されることを示しています。
「フィルタパターン」は3つのパラメータの組み合わせです:イベントコード、送信者番号とイベントデータです。1つ、2つ、または3つすべてのフィルタを使用できます。- 0に等しいイベントコードは、イベントコードのワイルドカードです。
- この場合、送信者番号を指定するには、ターゲットアクターオプションを使用します (C#クライアントSDKでは、これは
RaiseEventOptions.TargetActors
配列を使用して行われます)。
送信者番号には0を指定することができ、「グローバルキャッシュ」から削除できることを意味します。
つまり、グローバルキャッシュから削除するためには、送信者番号に0を指定することができます。
target actorsは配列なので、グローバル(ActorNr == 0)と非グローバルキャッシュイベント(ActorNr != 0)を組み合わせて複数のアクターでフィルタリングすることも可能です。- また、イベントデータでフィルタリングする場合にはデータの一部を送信することもできます。
たとえば、イベン トデータとしてHashtable
を使用する場合、1つまたは複数のキー/値のセットを指定することでイベントを削除 可能です。
- また、イベントデータでフィルタリングする場合にはデータの一部を送信することもできます。
RemoveFromRoomCacheForActorsLeft
: 削除済みのアクターが送信したキャッシュイベントを、削除する必要があることを示しています。
デフォルトでtrueに設定されているRoomOptions.CleanupCacheOnLeave
を使用してルームを作成する場合と違いはありません。
RaiseEventOptions.Receivers == ReceiverGroups.MasterClient
.RaiseEventOptions.TargetActors != null
.RaiseEventOptions.InterestGroups != 0
.
使用例2:
イベントコンテンツとしてHashtable
を使用する場合、オブジェクトに属するすべてのイベントを「oid」キー(「ObjectID」の短縮形)と値でマークできます。
特定のオブジェクトに関連するキャッシュをクリーンアップしたい場合には、データフィルタとしてのHashtable(){"oid", <objectId>}
とEventCaching.RemoveFromRoomCache
を送信してください。
キャッシュクリーニング
プレイヤーがゲームを終了する際、通常そのプレイヤーの行動は通常は新しいプレイヤーには関連がありません。
ゲーム参加の停滞を防ぐため、ルームを退出したプレイヤーがキャッシュしたイベントをPhoton Serverはデフォルトでクリーンアップします。
ルームのイベントキャッシュを手動でクリーンアップするにはRoomOptions.CleanupCacheOnLeave
をfalseに設定してルームを作成する必要があります。
特別な留意事項
- Photonのクライアントはアクターが完全に参加しているときのみ、ルーム内でオペレーション(RaiseEvent、 SetPropertiesなど)の呼び出しを開始できません。
全てのキャッシュイベントの送信が完了したときのみ、アクターは完全に参加したとはみなされません。
クライアントがルーム内で全てのキャッシュイベントをはじめに受信する前にオペレーションを呼ぼうとすると、エラー(OperationNotAllowedInCurrentState (-3)
)を受信します。 - キャッシュイベントはまたアクターがルームに参加した後に送信されたライブイベントを遅延します。
- Photonはルーム毎のキャッシュイベント(アクターのキャッシュとグローバルキャッシュの結合)の合計数に上限を設けています。
上限に達すると、サーバーはErrorInfoイベントを送信し、
すべてのアクターが切断され、ルームはサーバーから削除されます。