2 - ネットワークコールバック
Boltでは、その他のほとんど(あるいはその他全て)のUnity用ネットワーキングソリューションとは全く異なるやり方で複製が行われます。
OnSerializeNetworkView をUnityネットワーキングソリューションにおけるビルドで用いるなどのようにデータのシリアル化のために手動でコードを書くのではなく、Boltではネットワーク上でそれ自体が自動で複製されるよう、変換やアニメーション、カスタムプロパティを定義することができます。コードを書く必要は一切ありません。
このチュートリアルでも、低階層のネットワーキングコードを書くようなことはありません。Boltが全てやってくれるのです。
カメラの追加
最初にするべきはカメラの設定です。これにより何が起こっているのかを見ることができるようになります。しかし、カメラをシーンに置くのではなく、Boltを通じてそのコールバックに接続するようにします。
最終的なチュートリアルには、必要な機能を有している既に機能しているカメラが付属しています。本チュートリアルは第三者視点のカメラを作成することを目的としていないため、これを逐語的に利用します。
Assets/samples/AdvancedTutorial/prefabs/singletons/resources/PlayerCamera
からカメラのプレハブを確認できます。関連するスクリプトは、Assets/samples/AdvancedTutorial/scripts/player/PlayerCamera.cs
にあります。
カメラスクリプトはユーティリティーベースクラスから継承され、これはBoltSingletonPrefab<T>
を呼び出すことでBolt内に定義されます。これは、Resources からプレハブを自動で読み込むのに用いられます。
最初のスクリプトをここで作成しましょう。フォルダ tutorial/scripts/Callbacks を作成し、TutorialPlayerCallbacks.cs
という名前のスクリプトを作成してください。その後、以下の手順にしたがってください:
- クラスを
Bolt.GlobalEventListener
から継承してください。 - 対象のシーン(ここでは Level2)を選択し、クラスに
[BoltGlobalBehaviour("Level2")]
注釈を適用してください。 Bolt.GlobalEventListener
から継承されるSceneLoadLocalDone
メソッドをオーバーライドしてください。このメソッドについての詳細は、APIページを参照してください。;- ファイルの最上部に
using Bolt.AdvancedTutorial;
を挿入し、PlayerCamera
クラスにアクセスできるようにしてください。 SceneLoadLocalDone
内でPlayerCamera.Instantiate()
を呼び出します(引数は不要です)。- 非常に重要な点ですが、この挙動はあらゆるシーンのあらゆるゲームオブジェクトに添付 しない でください。
C#
using Bolt.AdvancedTutorial;
using UnityEngine;
[BoltGlobalBehaviour("Level2")]
public class TutorialPlayerCallbacks : Bolt.GlobalEventListener
{
public override void SceneLoadLocalDone(string map)
{
// this just instantiates our player camera,
// the Instantiate() method is supplied by the BoltSingletonPrefab<T> class
PlayerCamera.Instantiate();
}
}
ゲームを開始する前に、ここで何が起こっているのかを説明しましょう。
[BoltGlobalBehaviour("Level2")]
は実際には何をしているのでしょうか。Boltが開始したとき、これは [BoltGlobalBehaviour("Level2")]
を含み MonoBehaviour
から何らかの形で継承されている 全て のクラスを見つけます。(Bolt.GlobalEventListener
自体は MonoBehaviour
からの継承であるため、TutorialPlayerCallbacks
もまた MonoBehaviour
からの継承と判断されます)
それから、Boltはこれらの2つの条件にマッチングするクラスを検索し、自動でそれらのインスタンスを作成します。これは、Boltが起動しているときに存在し、Boltがシャットダウンされたときには破棄されるようにするためです。
作成される全てのインスタンスは、開始時にBoltが自動で作成するBoltBehaviours
ゲームオブジェクトに追加されます。これはシーン階層で確認することができます。
[BoltGlobalBehaviour]
の挙動を設定するにはいくつかの方法があります。最もシンプルなものとして、その挙動がサーバー側で行われるかクライアント側で行われるか、あるいはその両方かを決めることがあります。
TutorialPlayerCallbacks
クラスで行ったように何も指定しなければ、サーバー上とクライアント上の両方で動作することとなります。
C#
// only on the host
[BoltGlobalBehaviour(BoltNetworkModes.Host)]
// only on the client
[BoltGlobalBehaviour(BoltNetworkModes.Client)]
また、Boltの挙動を特定のシーン内においてのみ利用可能にすることもできます。例えば、ここでのシーンは Level2 と呼ばれています。
C#
// only when the current scene is 'Level2'
[BoltGlobalBehaviour("Level2")]
// only when the current scene is 'Level1', 'Level2' or 'Level3'
[BoltGlobalBehaviour("Level1", "Level2", "Level3")]
これらを組み合わせることもできます。
C#
// only when we are the host AND the current scene is 'Level2'
[BoltGlobalBehaviour(BoltNetworkModes.Host, "Level2")]
// only when we are the client AND the current scene is 'Level2'
[BoltGlobalBehaviour(BoltNetworkModes.Client, "Level2")]
これによって、アプリケーション全体またはシーン全体への挙動を簡単に定義できます。DontDestroyOnLoad
でマーキングされたゲームオブジェクトをすべてのシーンに渡すことは不要です。重要 な点ですが、さきに述べたとおりどのような状況下でも手動でこれらのスクリプトをシーン内のオブジェクトに添付 しないで ください。Boltが自動で処理します。
カメラの開始
Window/Bolt/Scenes ウィンドウメニューを開き、Level2 シーンで Play As Server をクリックしてください。
これで Game ウィンドウ内でサーバーが開始し、カメラがインスタンスを作成することを確認できます。
シーン階層を見ると、BoltBehaviours と名前のついたゲームオブジェクトを確認できます。これは Bolt の内部オブジェクトであり、この時点でこれを完全に可視化(HideFlagがない状態)しました。これで何が起こっているのかを常に知ることができます。
このオブジェクトに対するインスペクターをチェックすると、Boltが自動でインスタンス化する内部のすべての挙動を見ることができ、TutorialPlayerCallbacks
の挙動は下部で見ることができます。SceneLoadLocalDone
コールバックでインスタンスが作成されたPlayerCamera
を確認することもできます。
プレハブの作成
新規に空のゲームオブジェクトを作成し、それに TutorialPlayer と名前をつけてください。これの位置が(0, 0, 0)、回転が(0, 0, 0)、スケールが(1, 1, 1)となっているか確認してください。
これから用いるモデルは、bolt_samples/AdvancedTutorial/art/models/sgtBolt にあります。そのプレハブ名は sgtBolt4Merged-ModelOnly となっています。このプレハブのインスタンスをその階層にドラッグしてください。
sgtBolt4Merged-ModelOnly オブジェクトが、TutorialPlayer ゲームオブジェクトと同じ位置・回転・スケール値を有していることを確認してください。
その後、下図のように sgtBolt4Merged-ModelOnly オブジェクトを TutorialPlayer オブジェクトの子としてドラッグしてください。
チュートリアルフォルダ内に新たなフォルダを作成し、Prefabs と名前をつけてください。TutorialPlayer オブジェクトをこのフォルダにドラッグし、そこからプレハブを作成してください。この時点で、シーン階層にある TutorialPlayer オブジェクトは消去しても構いません。
TutorialPlayer プレハブを選択し、Bolt Entity コンポーネントを追加します。
Bolt Entity コンポーネントは、UnityまたはPhotonの Network View に緩く関連づけされています。しかし、Bolt内においてそれ以外のいくつかの目的も成しています。
最初にすべきは、2つのエラーを解決することです。これは、トップメニューバーのBolt/Compile Assembly
メニューオプションから行うことができます。
Assets/Bolt/Compile Assembly メニューを起動すると、Boltは全てのプレハブおよびその他のBoltに関連するアセットを検索し、それらのために非常に効率的なネットワークプロトコルをコンパイルします。これはbolt.user.dll
アセンブリ内に保存されます。これは Assets/Photon/PhotonBolt/assemblies
フォルダで確認できます。
Assets/Bolt/Compile Assembly コマンドの起動を行うケースはいくつかありますが、このチュートリアルではその全てをカバーします。
コンパイルが完了したら、プレハブにおける Bolt Entity コンポーネントは以下のようになります。
ご覧の通り、Boltエンティティには状態が欠けているので、この点を次でカバーします。
Bolt内の状態
詳細を進む前に、Boltにおける "状態" について定義しましょう。状態とは、ゲームオブジェクトのデータ、変換、アニメーションです。
Boltではエンティティに対して割り当てた全ての状態が、変換やアニメーションも例外なく、ネットワーク上に複製されます(Mecanimだけでレガシーはサポートされません)。
Unity用のその他のネットワーキングソリューションと比較し、Boltはネットワーク上にてデータを送信する際に大きく異なるアプローチをとります。
シリアル化 、非シリアル化 、補間 コードを手動で書く代わりに、BoltではUnity Editorの内部から便利なインターフェイスによりデータや相互作用の定義を行うことができます。
将来的にはDSLを追加し、これにより同じものをテキスト内で定義することができるようになります。
ネットワーキングアセットの定義を行う上でBoltで利用可能な編集ウィンドウは2つあります。これはBolt/Assets
ウィンドウにあります。
Bolt Assets ウィンドウを開くと、完成したチュートリアルプロジェクトに付属している既存のアセットのリストを確認することができます。
まず始めに、TutorialPlayer
プレハブのための状態を作成しましょう。 Bolt Assets ウィンドウ内で右クリックをして、New State を選択してください。
Boltが自動的に編集ウィンドウを開かない場合、新たに作成された状態である NewState をクリックしてください。
以下の手順に従って、この新しい 状態 の設定をおこないます。
- この状態の名前を TutorialPlayerState と設定します。
- 新しい Property を作成します。
- Transform とリネームします。
- タイプを
Transform
に変更します。 Replication
モードをEveryone Except Controller
へ変更します。;
Transform
に関する特別な設定については、そのままにしておいてください。
これらによって、プロパティの優先化やアルゴリズムの円滑化などのより複雑な点について設定が可能です。
Bolt/Compile Assembly
メニュー を再度実行します。
TutorialPlayer プレハブを再度選択し、Prefab & State / State の下の Bolt Entity コンポーネント上の ITutorialPlayerState
という状態を選択してください。
これはコンパイル後にBoltが生成するコードの一部です。状態 の定義に応じた内部レプリケーション実装用のネットワークインターフェイスです。
変更を保存するため、忘れずにプレハブ内の Apply ボタンを押してください。
現段階で、プレハブに行うことは以上です。後で、コード経由で State を使用しネットワーク上にのせるものを設定します。
シーン読み込みコールバック
ゲーム内にキャラクターをスポーンさせるためには、サーバー上のコールバックに接続してサーバーとクライアントの両方にプレハブのインスタンスを作成する必要があります。
TutorialServerCallbacks
という新規スクリプトを tutorial/Scripts/Callbacks フォルダの下に作成してください。
C#
using UnityEngine;
[BoltGlobalBehaviour(BoltNetworkModes.Host, "Level2")]
public class TutorialServerCallbacks : Bolt.GlobalEventListener
{
public override void SceneLoadLocalDone(string map)
{
BoltNetwork.Instantiate(BoltPrefabs.TutorialPlayer);
}
public override void SceneLoadRemoteDone(BoltConnection connection)
{
BoltNetwork.Instantiate(BoltPrefabs.TutorialPlayer);
}
}
TutorialServerCallbacks
のクラスはBolt.GlobalEventListener
から継承させてください。このクラスはBoltGlobalBehaviour
でデコレーションしてください。これはサーバー上での稼働および Level2 のシーンのみに対するオプションです。
シーンの読み込みに関連する2つのコールバックをオーバーライドしていきます。
SceneLoadLocalDone
: ローカルのコンピュータがシーンの読み込みを完了すると呼ばれます。またこの挙動はサーバー上で実行するようマークされているため、サーバー上でのみアクティブとなります。SceneLoadRemoteDone
:(BoltConnection connection
) に渡されている接続のリモートのエンドがシーンの読み込みを完了した際に呼び出されます。この動作もサーバー上でのみ実行されるため、クライアントが現在のシーンの読み込みを完了したときに通知されます。
どちらのメソッドについても、TutorialPlayerプレハブのコピーをインスタンス化します。
BoltPrefabs
クラスにはBoltエンティティのプレハブそれぞれに対するフィールドが含まれています。そのため、その全てについて簡単にアクセスすることができます。
サーバーのインスタンスを開始するには、Bolt Scenes ウィンドウの Play As Server ボタンを押してください。
シーンの前回の開始とはあまり大きな差はありませんが、階層を見ると、TutorialPlayer プレハブのインスタンスを確認することができます。
サーバーと接続する個別のクライアントを構築し、起動することもできます。階層内には TutorialPlayer プレハブのインスタンスを2つ確認できます。
Back to top