ご留意ください:Photon TrueSyncとThunderの開発は停止されており、今後はアップデートもパリリースされません。既存のアプリケーションへの影響はありませんが、現在開発中のアプリケーションについてはマイグレーションを推奨しています。

TrueSync チュートリアル セクション2

チュートリアルの内容

このチュートリアルのシリーズでは、Photon TrueSyncを使ってUnityでシンプルなマルチプレイヤーゲームを作る方法を説明します。セクション1では、TrueSyncをダウンロードしてインストールする方法を説明し、ゲームクライアントをPhoton Cloudに接続してPhotonルームに参加させるための基本的なPhoton Unity Networkコードを紹介しました。

セクション2の内容:

ルームに接続された各プレイヤーに対してボックスをインスタンス化するゲームクライアント。プレイヤーは自分のボックスを動かすことができ、すべての動きは、各プレイヤーの入力をクライアント間で送信することによって同期されます。

TrueSyncManagerプレハブとコンポーネント

このチュートリアルのセクション1で作成した「Game」シーンを開きます。シーンにTrueSyncManagerプレハブを挿入します(Unityメニュー:Game Object/TrueSync/TrueSyncManager)。シーンの階層は次のようになります:

scene hierarchy with truesyncmanager
TrueSyncManagerのシーン階層

TrueSyncManagerプレハブには、TrueSyncManagerとも呼ばれるコンポーネントが含まれており、そのコンポーネントでTrueSyncの更新を呼び出し、ロックステップのシミュレーションを制御します。

truesyncmanager component
TrueSyncManagerコンポーネント

TrueSyncのオプションのほとんどは、このチュートリアルのセクション4で扱う別のアセットで設定されるので、ここで追加する必要があるのはプレイヤープレハブのみです。

TrueSyncManagerオブジェクトを含むシーンを保存することを忘れないでください。

プレーヤプレハブの作成

プレイヤープレハブは、ゲームセッション/ルームに接続された各プレイヤーのためにコピーをインスタンス化するゲームオブジェクトです。

次のセクションで説明するように、コードでオブジェクトをインスタンス化することはできますが、TrueSyncにはプレイヤーが制御するオブジェクトを自動的に作成する便利な方法があります。

次にUnityメニューを使用して、この例に必要な確定論的な物理コンポーネントを含むTrueSync Cubeを作成します。 "GameObject/TrueSync/Cube"をクリックするだけで作成できます。

TSRigidbodyコンポーネントを以下の画像のように設定します。コードで動きを制御するので、重力の影響を受けないようにkinematicにチェックを入れてください。また、ゲームオブジェクトのTagが "Player"に設定されていることを確認してください。

tsrigidbody component
TSRigidbodyコンポーネント

ゲームオブジェクトの名前を "PlayerBox"に変更し、それを "Tutorial"フォルダにドラッグして、新しいプレハブに保存します。

シーンからゲームオブジェクトを削除し、前に作成したTrueSyncManagerオブジェクトのプレハブへの参照を追加する必要があります。これを行うには、TrueSyncManager内のプレイヤープレハブの数を1に変更し、プレハブを「Tutorial」フォルダから開いているスロットに以下の図のようにドラッグします。

player prefab referenced in truesyncmanager
TrueSyncManagerで参照されるプレイヤーのプレハブ。

各クライアントでは、TrueSyncがルームに接続された各プレイヤーのプレイヤープレハブのコピーを作成します。 TrueSyncはオフラインモードでも動作しますので、エディタから "Game"シーンをテスト実行し、PlayerBox(Clone)オブジェクトが階層に自動的に作成されているかどうかを確認できます(下図参照)。

instantiated player prefab in the scene
シーンのインスタンス化されたプレイヤープレハブ。

このセクションの終了後に必ずシーンを保存してください。

PlayerプレハブにTrueSyncBehaviourを追加

TrueSyncはロックステップシステムなので、同期されるのはプレイヤーの入力のみです。このチュートリアルでは、プレイヤーが自身のボックスの移動のみを制御するよう、そのように動作するスクリプトを追加します。

チュートリアルフォルダに新しいC#スクリプトを作成し、 "PlayerMovement.cs"と名付けます。以下のコードのようにしてください。

C#

using UnityEngine;
using System.Collections;
using TrueSync;

public class PlayerMovement : TrueSyncBehaviour {

}

このスクリプトは "TrueSyncBehaviour"から継承しています。つまり、ほとんどの場合、Unityのデフォルトではなく異なるコールバックを使用します。Unityは決定論的ではないので、代わりに、ゲームオブジェクトをロックステップのゲームループで制御するためです。

次に、以前に作成したPlayerBoxプレハブにスクリプトを添付してください。そうすることで、TrueSyncがそのコピーをインスタンス化すると、「PlayerMovement.cs」スクリプトがそれに含まれます。

シーンを保存すると、プレハブとリファレンスも保存されます。

入力の収集とキューイング

ロックステップシステムは、すべてのプレイヤーの入力を使用して、すべてのクライアントで同時にシミュレーションを実行します。そのため、フレームごとの結果は常に同じになります。

これが機能するためには、Unityの入力を使用して直接ゲームオブジェクトを操作したり、ゲーム状態の値を変更することはできません。

代わりに、Unityからプレイヤー入力値を収集しTrueSyncの入力システムにキューイングするコードを追加して、すべてのゲームクライアントに配布できるようにします。これは、後で説明する別のアップデート方法で使用するためにローカルのクライアントも含みます。

次のコードは、Unityの入力軸の値をTrueSync入力キューに登録します。 「PlayerMovement.cs」に追加します。

C#

public override void OnSyncedInput() {
    FP accell = Input.GetAxis ("Vertical");
    FP steer = Input.GetAxis ("Horizontal");

    TrueSyncInput.SetFP (0, accell);
    TrueSyncInput.SetFP (1, steer);
}

OnSyncedInputカスタムコールバックの内部からこれを行います。このコールバックは、ローカルプレイヤーオブジェクトに対してのみ呼び出されます。リモートプレイヤーが所有するオブジェクトは、このコールバックを自身のマシンでのみ実行します。 TrueSyncはすべてのマシン間の入力の交換を行います。

また、floatからFixedPoint(FP)に変換することも重要です。この先のすべての計算を異なるマシンやプラットフォーム間で決定論的にするためです。次のセッションでは、これに関する詳細を追加します。

箱を動かす

TrueSyncにより軸入力がマシン間でキューに入れられ、配布されたので、これを使用してプレイヤーボックスを移動してみましょう。"OnSyncedUpdate"という別のカスタムコールバックの中でこれを行います。これは、すべてのプレイヤー(ローカルプレイヤーを含む)の特定のティック/フレームのすべての入力が利用可能な場合にのみ、TrueSyncに呼び出されます。

C#

public override void OnSyncedUpdate () {
    FP accell = TrueSyncInput.GetFP (0);
    FP steer = TrueSyncInput.GetFP (1);

    accell *= 10 * TrueSyncManager.DeltaTime;
    steer *= 250 * TrueSyncManager.DeltaTime;

    tsTransform.Translate (0, 0, accell, Space.Self);
    tsTransform.Rotate (0, steer, 0);
}

TrueSyncInputキューからFixedPoint (FP) 入力値を取得し、それをTrueSync独自のバージョンの(マシン間で決定論的)DeltaTimeと速度係数で乗算しています。

この時点でUnityのエディタから固定速度係数を較正する場合は、FixedPoint属性で固定速度属性を置き換えることができます。

2つの値は、ボックスの移動/回転に使用されます。これを行うには、 "Translate"と "Rotate"メソッドを使用しますが、これをUnityの変換ではなく "TSTransform"コンポーネントに適用してください。

tsTransform変数は、 "TrueSyncBehaviour"を継承するスクリプトのために "TSTransform"コンポーネントにあらかじめ参照されています。

TrueSyncではすべてのゲームプレイコードが確定的である必要があり、Unityのサブシステムのほとんどは保証されていないため、これが必要です。

TrueSyncには、UnityのAPIを模倣した複数のコンポーネントが含まれており、簡単にロックステップゲームの制作が行なえます。2つのカスタム確定論的物理エンジン(2Dおよび3D)、Transformコンポーネント(TSTransform)、FixedPointタイプ(FP)、Seededランダム(TSRandom)、数学ライブラリ(TSVector、TSMatrix、TSQuaternion)などがあります。

プレイヤープレハブのスクリプトがTrueSyncにキューを入力するようになり、カスタムアップデートコールバックでこの入力を使用してボックスを移動するようになりました。マルチプレイヤーモードでコードをテストしてみましょう(シーンをエディタから直接実行することでオフライン/シングルプレイヤーモードでいつでもこのコードをテストできます)

「PlayerMovement.cs」スクリプトを「プロジェクト」タブの「PlayerBox」プレハブに添付していることを確認してください。

プレイヤーボックスが動き回るのを確認するためにカメラをより良い位置に置くことをお勧めします。Transformコンポーネントには、次の値を使用することをお勧めします。

camera transform in game scene
ゲームシーンでのカメラ変換。

テストの実行

両方のシーン (Tutorial/Menu とTutorial/Game) がビルド設定に含まれていること、また、Tutorial/Menuが最初のシーン(起動時にUnityが読み込むもの)であることを確認してください。

任意のビルドを作成し、1つ、または2つのコピーを実行して、Unityエディタ内からMenuシーンを実行します。

これで、両方のクライアントがPhotonに接続して、各クライアントが独自のボックスを制御するゲームシーンが読み込まれます。

それではセクション3に移動して、投射物の射撃を同期する方法を学びましょう。

Back to top