イベント

目次

イベントとは、ネットワークを介したRPCのような呼び出しを設定するためのBoltの方法です。 ここでは、Photon Boltで作成できるイベントの種類、それらの主な違い、利用シーンについて説明します。

Boltがイベントをどのように扱うかについては、Boltはイベントを別のパケットとして送信しないことを覚えておいてください。 BoltはSendRateに基づいて送信する毎に、すべて(状態、イベントなど)を1つのパケットにまとめて送信します。

イベントの種類

グローバルイベント

グローバルイベントは Create または Post メソッドに異なるパラメータを渡すことで ReliableOrdered または Unreliable の両方を指定することができます。 一般的に、ほとんどのグローバルイベントは Reliable モード (デフォルトモード) で送信されます。

グローバルイベントは接続レベルで送信され、特定のエンティティに送信されるわけではありません。つまり、対象プレイヤーはサーバーに接続していればこれらのイベントを受信することができます。 これらのイベントは、次のように、ゲームの周辺に存在するものを対象としています。

  • 認証への対応。
  • プレイヤーのインベントリの扱い。

グローバルイベントにはいくつかのオーバーライドがあり、誰がイベントを受け取るかを微調整することができます (ユーザーインターフェイスの Bolt Event で定義されているか、コードでオーバーライドされているかのいずれか)。

トップに戻る

エンティティイベント

Entity Eventは常に信頼性が低く、ダメージインジケータを表示したり、爆発を再生したりするような小さな一回限りの効果を目的としています。つまり、一時的なものであり、1人のプレイヤーがそれを逃した場合、問題にならないものです。

エンティティイベントは常に特定のBoltEntityに送られます。つまり、BoltEntityコンポーネントなどから取得するか、ターゲットエンティティへの参照が必要です。

トップに戻る

イベントの信頼性

信頼性の高いイベント

Boltでの信頼性の高いイベントは、送信された順番に到着することが保証されています。 Boltで送信できる信頼性の高いイベントは Global Eventだけです。

信頼できるイベントごとに3バイトのオーバーヘッドがあります。

トップに戻る

信頼性の低いイベント

一方では、信頼性の低いイベントは、Boltによって異なる扱いを受けます。 Boltは、後続の2回の送信ティックでパケットにイベントをパックしようとします。 基本的にBoltは、スペースが残っている場合は、パケットの最後に信頼性のないイベントを入れようとします。 2つの後続のパケットでパケットにイベントを入れようとし、それ以降はあきらめて、イベントを削除します。 この文脈での「信頼できない」は、伝統的な意味での「信頼できない」ネットワークパケットとは何の関係もありません。

信頼できないイベントごとに1バイトのオーバーヘッドがあります。

トップに戻る

バッファリング

Boltはイベントをバッファリングしません。 エンティティのイベントが(エンティティイベントを経由して)到着し、エンティティが存在しない場合、Boltはイベントをドロップします。 信頼性の高いエンティティイベントが必要な場合は、エンティティをイベントのフィールドとして使用するグローバルイベントを使用します。 ただし、Boltはイベントとステートを1つのパケットにまとめているため、送信のタイミングごとにすべてがパケットになるわけではありません。つまり、エンティティを作成した直後にエンティティにイベントを送信しようとすると、エンティティが作成される前や後にイベントが届くことがあることがわかります。 Boltイベントとエンティティは、パケット内の別の論理ストリームで作成され、それらはお互いに順序付けされません。

トップに戻る

ボルトイベント生成

新しいイベント定義を作成するには、Bolt Assets ウィンドウ (Bolt/Assets メニュー) に移動し、右クリックをして New Event を選択します。 Bolt Editor ウィンドウでは、イベント名を設定したり、誰がこのイベントを送信できるかを設定したり、イベントを定義するすべてのプロパティを作成/設定したりすることができます。

重要な点の一つは、誰がイベントを送信できるかということです。 Global Eventでは、以下のいずれかを選択することができます。 (i) Everyone サーバとクライアントの両方のピアがこのイベントをグローバルに送信できることを意味します。 (ii) Only Server サーバだけがそのようなイベントを作成することができるようにします。 (iii) Only Clients すべてのクライアントが送信できますが、サーバは送信できません。 (iv) None の場合、誰もこのイベントをグローバルに送信することはできません。 Entity Eventのオプションは以下の通りです。 (i) Everyone 誰もがこのイベントを送信できるようにします。 (ii) Only Owner の場合、エンティティを作成したピアのみがこのイベントを送信できます。 (iii) Only Controller このエンティティからイベントを送信できるのはエンティティコントローラだけです。 (iv) None 誰もこのイベントをエンティティイベントとして送信できないことを意味します。

Event Definition
Event Definition.

イベントを定義したら、Boltをコンパイルする必要があります ( Bolt/Compile Assembly メニュー)。 このとき、Bolt は Bolt Event クラスから派生したイベント用の新しいクラスを生成します。 つまり、イベント EventTest を作成した場合、Bolt はイベントのメタデータを生成します (このイベントのメタデータは Visual Studio で右クリックして Go To Definition をクリックすることで確認できます)。

public class EventTest : Event
{
    // ...
}

その後、静的作成メソッドのいずれかを使用してイベントを作成できます。 これらの各メソッドでは、エンドポイント情報を指定することができます。 ターゲット情報を指定しない場合は、Bolt で指定したイベントのデフォルトが使用されます。 特定の接続にイベントを送信したいだけの場合は、そのためのオーバーライドがあります。

// For Global Events
public static EventTest Create();
public static EventTest Create(ReliabilityModes reliability);
public static EventTest Create(GlobalTargets targets);
public static EventTest Create(GlobalTargets targets, ReliabilityModes reliability);
public static EventTest Create(BoltConnection connection);
public static EventTest Create(BoltConnection connection, ReliabilityModes reliability);

// For Entity Events
public static EventTest Create(BoltEntity entity);
public static EventTest Create(BoltEntity entity, EntityTargets targets);

イベントを作成したら、イベントにデータを入力することができます。 Bolt コードジェネレーターは、Bolt でイベントを作成し、Bolt をコンパイルした際に追加したすべてのデータのフィールドを生成します。 例えば、このイベントのために MyField というフィールドを integer として、MyText というフィールドを String として Bolt に追加した場合、次のようになります。

void SendEvent()
{
    // Create and setup
    var myEvent = EventTest.Create(GlobalTargets.AllClients);
    myEvent.MyField = 5;
    myEvent.MyText = "hello event!";

    // Send the event
    myEvent.Send()
}

CreateAPIを拡張して、Boltは Post という名前のメソッドも作成します (Boltのバージョン 1.2.13 以降で利用可能)。このメソッドは、上で説明した Create メソッドとまったく同じシグネチャを持ち、イベントのすべてのフィールドのパラメータを含むものです。 また、Post メソッドは呼び出されたときに自動的にイベントを送信します。 そのため、先ほどのコードスニペットは次のように書き換えることができます。

void SendEvent()
{
    // Create, setup and send
    EventTest.Post(GlobalTargets.AllClients, 5, "hello event!");
}

どちらの方法を使っても問題ありません。

トップに戻る

グローバルイベントの受信

Bolt.GlobalEventListenerからクラスを派生させてシーンに追加することで、グローバルイベントを受信することができます。 Boltは自動的にすべてのGlobalEventListenersを見つけて、Boltの起動時にシーンにあれば登録します。 ただし、Boltはシャットダウン後に登録を解除するので、シングルトンリスナーを使用していてリスナーを持続させたい場合は、派生クラスで PersistBetweenStartupAndShutdown をオーバーライドして true を返すようにしてください。

また、GlobalEventListener派生クラスを [BoltGlobalBehaviour()] で装飾することができ、さまざまなパラメータを使用して、Boltの起動時にリスナーが自動的に作成されます (この属性を使用する2つの一般的なシナリオは、ネットワークタイプ固有のリスナーを追加することです (すなわち、クライアント対サーバー) またはシーン固有のリスナー)。 これはチュートリアルで使用されます。

GlobalEventListener 派生クラスがあれば、興味のある Global Event のイベントハンドラをオーバーライドして、イベントを受信するためのロジックを実装することができます。

また、BoltNetwork.AddGlobalEventListenerBoltNetwork.RemoveGlobalEventListenerで独自のリスナーを登録することもできます。 また、GlobalEventListenerを忘れて、自分でインターフェースを実装して、リスナーを手動で登録することもできます。

イベントに設定したプロパティに加えて、Boltには、どこかの時点で便利そうな他のフィールドもいくつか含まれています。

  • evt.FromSelf:このイベントが自分自身の接続から送信された場合は真を返します。
  • evt.IsGlobalEvent:このイベントがグローバルイベントの場合は true、エンティティイベントの場合は false を返します。
  • evt.RaisedBy:このイベントを発生させた接続。
  • evt.BinaryData:イベントデータの生のバイト数。

これらのプロパティの詳細については、API Docs をご確認ください

トップに戻る

IEventListener

このインターフェイスは Bolt.GlobalEventListener, Bolt.EntityEventListener, Bolt.EntityEventListener<T> に実装し、MonoBehaviour/GameObject が無効になっていてもイベントが発生するかどうかを変更することができます (デフォルトでは発生しません)。

public interface IEventListener
{
    bool InvokeIfDisabled { get; }
    bool InvokeIfGameObjectIsInactive { get; }
}

Example:

[BoltGlobalBehaviour(BoltNetworkModes.Server)]
public class BoltServerCallbacks : Bolt.GlobalEventListener, Bolt.IEventListener
{
    public bool InvokeIfDisabled { return true; }
    public bool InvokeIfGameObjectIsInactive { return true; }

    // event callback overrides below
}

ドキュメントのトップへ戻る