マルコ・ポーロ・チュートリアル

マルコ・ポーロ・チュートリアルは、Unity3Dベースのチュートリアルです。Photon Cloudで動作するマルチプレイヤーアプリケーション開発の方法を紹介します。

目次

概要 Walking Vikings(ウォーキング・バイキングズ) Photon Cloud 最初から始める 受付:ルームを取得する マルコポーロ:ポジションを同期する 叫び、応える “それ”を切り替える 結論

概要 

このチュートリアルの最初の部分は、Photon Unity Networking(略称PUN)の デモの一つを段階的に紹介します。PUNパッケージをインポートし、Photon Cloudを使用 するためにそれをセットアップし、テストランを行います。

第2部では、Photon Unity Networking・パッケージとPhoton Cloudサービスを利用したマルチプレイヤー機能の開発を教えます。 必要とするもの

What you need

このチュートリアルは、あなたがUnityエディター使用とプログラミングの基本を知っていることを 前提としています。サンプルコードは、C#で記述されていますが、Unity Scriptで同様に機能します。

もくじへ戻る

Walking Vikings(ウォーキング・バイキングズ)  

アセットストアからPhoton Unity Networkingサンプルの“Viking Demo”を 試してみましょう。

Photon Cloud: Marco Polo Vikings

必要なものは全てはパッケージにありますので、Unityで新規の空のプロジェクトを作成します。 アセットストア内で “Photon Viking デモ” を検索してください(またはリンクをクリック)。パッケージをダウンロードし、Unity内にインポートしてください。

パッケージをインポートすると、エディタで「PUN Setup Wizard」ウィンドウが開きます。 後に詳しく説明します。

プロジェクト内に次の3つのフォルダができました:「DemoVikings 」、「Photon Unity Networking」「Plugins」。プロジェクトで必要な全てのネットワークコードはPUNとPluginsディレクトリにラップアップされます。 「Vikings」フォルダには、サンプルが含まれています。

Photon Cloud Screenshot: Viking Demo

ウィザード

PUNセットアップウィザードではネットワークを設定することが出来、マルチプレイヤーゲームを 開始するための非常に便利な方法も紹介されています。Photon Cloud!

クラウドですか。はい、クラウドです。それはゲームに使用することができるPhotonサーバ群です。少し説明しましょう。

Cloudの登録

Photon Cloud Screen Shot: Cloud registration

"永久無料プラン"は無料であり、義務を伴いませんので、メールアドレスを入力するだけで、ウィザードがその魔法をやってくれます:

メールアドレスがクラウドに知られていない場合、“AppId(アプリケーションID”を直ちに取得します。そして、メールです。

メールアドレスがすでに登録されている場合、ダッシュボードを開くよう指示されます。ログインしてAppIdをフェッチし、インプットフィールドにペーストして下さい。

AppIdが保存されたらこのステップは終了です。

PUNバージョン1.60以降では、`PhotonServerSettings`ファイルの「Auto-Join Lobby」にもチェックをする必要があります。プロジェクトウィンドウで、それを設定するファイルを検索し、選択します。これでPUNはルームリストを提供する、デフォルトのロビーに参加します。

Walking the Viking(ウォーキング・ザ・バイキング)

全部完了したら、アクションを取る時間です。マルチプレイヤー・アクションです!

シーン DemoVikings\Scenes\VikingSceneを開き、スタンドアロンとして、デモをビルドし、実行してください。

“メインメニュー”がポップアップし、プレイヤー名とルーム名を入力することができ、 (空の) “ルームリスト”があります。ルームを“作成"すると、シーンが切り替わり、最後にバイキングが現れます。1つだけですが、ここからスタートです。

エディターでもデモを開始すると、“ルームリスト”には1つの入室が表示されます。ルームに“入室”すると、ついにバイキングがあります(複数)。

さらにいくつか開始しそれぞれを実行することが出来ます。カメラは常に、クライアント毎に我々 “自身の”バイキングをフォローします。

Photon Cloud Screenshot: Marco Polo

ここでチュートリアルの最初の部分は終了です。PUNパッケージを取得、インポート、そしてセットアップする方法を学んできました。あなたのゲームをテストするためには、複数のクライアントを実行する必要があることを学びました。これは当たり前のことではありますが重要なことです。

もくじへ戻る

Photon Cloud 

Photon Cloud

では、“Photon Cloud” はいったい何をするものなのでしょう?!

基本的に、それはPhotonサーバを保有するPC群です。この“クラウド”サーバは、Exit Gamesによって保持されており、マルチプレイヤーゲーム用の使い勝手の良いサービスとして提供されています。サーバはオンデマンドで追加されますので、いかなるプレイヤー数でも対応可能です。

Photon Cloudは完全に無料ではありませんが、特に他の通常のホスティングに比較して、低コストです。 ここでの価格に関してさらにご覧ください。

Photon Unity Networkingは、あなたのためにPhoton Cloudを処理するものですが、内部的な処理を一言で説明すると以下のようになります。全ての人は初めに"Name Sever"に接続します。そこでクライアントがどのアプリ(AppIdで識別)とどのリージョンを使いたいかを識別します。その後Master Serverへクライアントを転送します。

Master Serverは数多くのリージョナルサーバのハブです。Master Serverは全ての既存のゲームを認識しています。ゲーム(ルーム)が作成されたり参加されたりする時、クライアントは"Game Sever"と呼ばれる他のマシーンへ転送されます。

PUNにおけるセットアップは極めて簡単ですので、ホスティングコスト、パフォーマンス、または保守に関して気にする必要がありません。いつでもです。

ルーム

Photon Cloudは“ルームベースのゲーム”を想定して構築されており、つまりゲームごとの参加プレイヤー数に上限があり(例えば:10人以下)、ルーム内のプレイヤーはその他のプレイヤーから隔離されます。ルームでは(普通は)、誰もが他者が送信するすべての情報を受信します。ルームの外ではプレイヤーはコミュニケーションが出来ないため、プレイヤーには可能な限りすぐにルームに入ってもえるようにします。ルームに参加する最善の方法はRandom Marchmakingを使うことです。サーバへ任意またはある条件付きのルームを要求するだけです。

ルームには識別するための名称があります。ルームが満員または閉まっていない限り、ルーム名で参加することが出来ます。Master Server はアプリへルームのリストを提供する事ができるので便利です。

ロビー

あなたのアプリケーション用のロビーは、あなたのゲーム用のルームをリスト化するマスターサーバ上にあります。PUNは自動的にこのロビーに入り、ルームのリストを取得します。それは、厳密には必須のものではありません:あなたがその名称を知っていたり、ランダムゲームに参加する場合は、直接ルームに入室することができます。

新しいPUNのバージョンでは、「Auto-Join Lobby」の設定はPhotonServerSettingsで行われます。デフォルトは、ロビーに参加しないことです。

アプリケーションIDとゲームのバージョン

誰もが同じサーバに接続する場合、あなたのプレイヤーと他のプレイヤーを分ける方法がなくてはなりません。

Each game (アプリケーションにあるように)各ゲームにはクラウド内でそれ自身の“AppId(アプリケーションID”があります。プレイヤーは常に、クライアントにおける同じ“AppId”を持つ他のプレイヤーのみに出会います。

また、“ゲームのバージョン”を使うことで新たなクライアントのプレイヤーと古いクライアンのプレイヤーを区別する事が出来ます。

もくじへ戻る

最初から始める 

新たなことを始めましょう。簡単なチュートリアルために、次のMMOではなく、モンスターがいるマルコポーロゲームを製作します。マルコポーロゲームについてはWikipediaの説明を参照ください。ここでは基本を示しますので、それを元になにか構築することができるはずです。

新規の空のプロジェクトを作成することから始めます。今回は、「Photon Viking Demo」のインポート時に、 「DemoVikings」フォルダのチェックを外します。ウィザードが開いたら、AppIDを入力してください。PhotonServerSettingsを選択し、「Auto-Join Lobby」にチェックをしてください(このチュートリアルで必要)。

もくじへ戻る

受付:ルームを取得する 

次に進む前に、プレーヤーをルームに入れる必要があります。 ルームでは動き回って、他の人に見せることができます。

「Marco Polo」フォルダと新しいC#スクリプト「RandomMatchmaker」を作成してください。UnityのStartメソッドが含まれています。 これは、できるだけ早く接続するのに最適な場所です。

PUNパッケージの最も重要なクラスはPhotonNetworkです。これは、UnityのNetworkクラスに似ていて、使用する殆どのメソッドが含まれています。

すでにPhotonServerSettingsファイルにAppIDを保存したので、PhotonNetwork.ConnectUsingSettingsを呼ぶことで接続できます。 gameVersionパラメータは、このバージョンを識別するための任意の短い文字列になります。 "0.1"を使用してみましょう。

プレイモードでは、接続されて、ロビーに入ります。しかし、出力は一切ないので、気づくことができません。状態を表示させましょう! 最小のGUIを使用したコードは次のようになります:

このスクリプトはシーンにまだありません。新規で空のGameObjectを作成し、それを“Scripts”と名付けます。これで後でそのスクリプトを見つけるのが簡単になり、我々はカメラに依存しません。RandomMatchmamkerをスクリプト(GameObject)に加え、保存し実行してみましょう。ラベルサイクルはいくつかのステイタスを経たのちにロビーで終了します。もしOnConnectedToMasterで止まった場合はPhotonServerSettingsで"Auto Join Lobby"を有効にしてください。

PUNによる呼び出し

Unityのように、何かが発生するとPUNはコードで特定のメソッドを呼び出します。 現在は、 「ロビーに到着」、「ルームを検出」と 「ルームの検出失敗」などが関連しています。

PUNはPhotonNetworkingMessageという名前の列挙型でコールバックを定義します。

しかし、コードで簡単にコールバックを実装するためには、クラスを少し変更するべきです:RandomMatchmakerで「MonoBehaviour」を見つけ、Photon.PunBehaviourで置き換えてください。ファイルの先頭に、using Photon;を追加してください。これはPunBehaviourのNameSpaceです。

これでクラスはPunBehaviourになり、個々のコールバックを上書きすることができます。OverrideとタイプするとIDEはそれらをリストするので、見つけるのが簡単です。

IDEが基本メソッドに呼び出しを追加した場合、それを削除してください。PUNコールバック用に空のベース実装を呼び出す必要はありません。

注意:コールバックはPunBehaviourのオーバーライドである必要はありません!メソッドは名前とパラメータのシグニチャーに適合する必要があります。また、パラメータ無しでそれらを実装することもできます。

OnJoinedLobby

PUNにおけるコールバックの方法の1つはOnJoinedLobbyです。PUNがあなたをロビーに入れる時にそれが呼び出されます。

しばらく、我々は今取得したルームのリストを無視し、その代わりに、早くルームに入ろうとします。PhotonNetworkクラスにはJoinRandomRoomの方法があります。これはどのルームへも我々を入れようとします。やってみましょう。

この反復を実行する時に、 connectionStateDetailedはまだJoinedLobbyで終えます。明らかにJoinRandomRoomはある理由のためにまだ機能しません。

このコールバックが呼び出されていないときは、PhotonServerSettingsで「Auto-Join Lobby」が有効になっていることを確認してください。

エラーの処理

エラーの場合は、PUNは、ログおよびコンソール(Ctrlキー+ Shiftキー+ C)を使用します。何かが予想通りにいかず、コンソールに出力がない場合は、PhotonNetwork.logLevelで「より高い」ログレベルを設定することができます。

出力の例:

Photon Cloud Screenshot: Marco Polo Photon View

このチュートリアルでは、デフォルトのログレベルを残して、エラーが発生した場合だけ、ログとコンソールに情報を出力するOnPhotonRandomJoinFailed()コールバックを追加します。OnPhotonJoinRoomFailedと似ているので混同しないでください。(それはルーム作成に失敗した時に使われます)

ルームの作成

誰もプレイしていない場合、または全てのルームがプレイヤーで満室となっている場合、ランダムのルームに入ることはできません。我々はこれを我々のプレイヤー(GUIの作業は練習として残しています)に示し、すぐに彼女に再度試させることも可能です。我々はこれをスキップし、単にルームを作成します。

我々はOnPhotonRandomJoinFailedを実行し、PhotonNetwork内での“ルームを作成する”方法を探します。完全な組み合わせがあります。CreateRoomです。tooltipによると2つのオーバーロードが存在し、ルーム名にnullをパスするとそのなかの一つ(GUID)を受け取ることになります。ルームの名称を示さないので、我々は気にせず、空白をパスします。

実行してコードを試してください。詳細の状態は、前よりも頻繁に変化しており、“Joined(入室した)”で終了します。我々はまさにルームの中にいます!

もくじへ戻る

マルコポーロ:ポジションを同期する 

Vikingsが走り回るのは見ているので、同じことをしてみましょう。 まず、「モンスター」のキャラクターをダウンロードしてください。これはAsset Storeにもありますが、私たちが使用したいのはリンクされたバージョンです。

このプレハブを名前からインスタンス化するので、Resourcesフォルダにある必要があります。 アセット「monsterprefab」を選択して、PhotonViewコンポーネントを追加します。コンポーネントのメニューにあるカテゴリ「Photon Networking」にあります。

PhotonView

UnityのNetworkingをご存知の場合: PhotonViewはPUNにとってNetworkViewと同等です。 PUNはのネットワークの参照、オブジェクトの所有者と「observed(監視)」コンポーネントへの参照を保持するために、 インスタンス化されたプレハブ毎にPhotonViewを必要とします。

PUNは、インスタンス化したPhotonViewをローカルで管理し、監視されたコンポーネントは実行時に他のクライアントに更新を送信することができます。監視されたオブジェクトが増えるにつき、より多くの作業とネットワークトラフィックが発生します。

「monsterprefab」の変換を監視するための新しいPhotonViewを設定するには、 「observed」フィールドにTransformコンポーネントをドラッグ&ドロップします。PhotonViewの他の設定を変更する必要はありません。

Photon Cloud Screenshot: Marco Polo Photon View

モンスターの追加

同じルーム内の全員が見ることができるモンスターをインスタンス化するためには、PhotonNetwork.Instantiateを使用する必要があります。これは、このインスタンスにViewIDを割り当て、モンスターを配置する場所を他のプレイヤーに知らせます。これを機能させるには、インスタンス化するためにResourceプレハブにPhotonViewが必要です。

ルーム内の他のプレイヤーを更新しない、UnityのInstantiateと混同しないでください。

ルームに参加したときにこれを行いましょう。OnJoinedRoomでは、このようにPhotonNetwork.Instantiateを呼び出します:

これを実行すると、モンスターがポップアップして落下を開始します。 それでは、地面を作成してみましょう。

接地

次のステップは一般的な“Unityの作業”です:シーンでの方向指示灯を作成し、ある角度に下げて向けるために回してください-太陽を真似ています。

平面を追加し、そのスケールを10, 1, 10にして、0, 0, 0に動かしてください。アセットストアからの材料を試しましょう。“18の無料の材料”パッケージをダウンロードし、それをインポートしてください。“Pavement_01”は見栄えが良いので、そのフォルダを開け、材料をその平面に適用します。検査者において、xとyに対して質感の傾きを1から10に変更してください。

Photon Cloud Screenshot: Marco Polo Textures

コントロールの追及

2つのクライアントを実行して再び進行状況を確認します。すべてのモンスターはキー入力によって移動され、カメラは動作しません。 モンスターと、入力およびカメラを処理するすべてのコンポーネントをクローンしました。

これを解決するためには無数の方法があります。一つの簡単な方法は、「monsterprefab」(!)のCharacterControlとCharacterCameraコンポーネントを無効にして”自分の”モンスターインスタンスにのみ利用可能にすることです。 PhotonNetwork.Instantiateはそれが作成したゲームオブジェクトを返すので、モンスターを修正するのは簡単です。 ただし一つだけ困難なことがあります:どちらのスクリプトもUnityScriptで書かれていて、C#コードにまだ知られていません。

一つの言語のスクリプトを他の言語のスクリプトで使用できるようにするには、プロジェクト内の「プラグイン」フォルダに移動します。 Monsterパッケージの「Scripts」フォルダを「Plugins」にリネームして、プロジェクトのルートに移動します(エディタでドラッグ&ドロップ)。

モンスターをインスタンス化した後、CharacterControlとCharacterCameraコンポーネントの 両方を有効にすることができます(私たちのモンスターのみ)。

スムーズな動き

今のところ、他のプレイヤーのモンスターは動きますが歩くことができません。アニメーションが不足しているためです。 また、位置は、モンスターをテレポートすることによって更新されます。これは、コードで解決することができます。

別のスクリプトが必要です。 Marco PoloフォルダにC#スクリプト「NetworkCharacter」を作成します。 「monsterprefab」に追加し、PhotonViewの監視されたコンポーネントにします(ドラッグ&ドロップ)。

スクリプトが監視されている間、 PhotonViewは定期的にメソッドOnPhotonSerializeViewを呼び出します。 他の人に渡したい情報を作成してそのような受信情報を処理することが目的です。 PhotonViewの作成者に依存します。

PhotonStreamはOnPhotonSerializeViewに渡され、 そこからリモートデータを書き込みまたは読み取りする必要がある場合、isWritingの値が知らせます。 まず、Position(位置)とRotation(回転)を送受信します。 これは、スクリプトなしのPhotonViewと同じ効果があります:

正しい位置にモンスターをスムーズに "プッシュ"する簡単な方法は、 時間の経過とともにそこにlerpすることです。

リモートモンスターの位置のみを滑らかにすることが目的です(自身のは問題なく動かせます)。スクリプトをPhoton.MonoBehaviourにすると(Photonのネームスペースに注意)​​、GameObjectのPhotonViewにアクセスできます。それは、後にisMineプロパティを提供します。

NetworkCharacterにVector3 correctPlayerPosとQuaternion correctPlayerRotを追加します。 OnPhotonSerializeViewでは新しい値を保存し、 Updateでそれらを適用します(少しずつ)。

他のプレイヤーのモンスターは同様の方法を用いて同じ速度を 実現することはありませんが、すぐに同じ場所に到達します。 ゲームによっては、キャラクターがどのようにたどり着くかより、 正確な位置に置くことの方が重要かも知れません。

アニメーションを加える

ここで問題が発生します:アニメーション状態は簡単につかむことはできません。複数のものが実行、ブレンド等されているので、これを同期する別の方法を見つける必要があります。

myThirdPersonControllerクラス(ショート:コントローラ)が解決に役立ちます。ほとんどのアニメーションをトリガーするのに_characterState変数を使用し、モンスターのCharacterController.velocityに基づいています。これはローカルで動作しますが、リモートコピーには速度がありません。ただ再配置されるだけです。

各モンスターがその状態を送信すると、コピーは受信する値を適用することができます。これは、最初にコントローラを無効にしていなければうまく動作します。

myThirdPersonControllerを使用したい場合、リモートインスタンスでも有効にする必要があり、「リモートモンスター」の入力を無視する別の方法が必要です。isControllable変数が良さそうです。常にチェックされるわけでなく、まだ設定されていませんが、どちらも修正することができます。やってみましょう。

ここでも、次の"スタンダード"なUnityの作業を行います: 「monsterprefab」にmyThirdPersonControllerを追加します。アニメーションが欠落しているので、それぞれのフィールド上にドロップして追加します。プレハブのTransform(最上のプレハブコンポーネント)をBulkフィールドにドラッグ&ドロップします。

CharacterControlとCharacterCameraはもう使用しないので、RandomMatchmaker.OnJoinedRoomからその有効コードを削除します。どちらのコンポーネントも、非アクティブのままになりました(除去することも可能です)。代わりに、RandomMatchmakerでモンスターを作成するときに、isControllableを設定します。

myThirdPersonControllerコードを開き、_characterStateをパブリックにし、isControllableをpublicかつfalseにしてください。入力が最初にisControllableをチェックし、それが我々のモンスターではない時に入力を無視するために使用する全ての場所を我々が見つける必要があります。続けてお読みください。

(myThirdPersonControllerで)コントロールできる場合のみ、インプットの軸を読みます。

isControllableでない場合、“ファイヤリング”を止めます:

そして、コントロールされない場合は誰もジャンプしません。:

注:元のスクリプトはアップデートを始める時点でInputをリセットしていました。それを削除してください!我々は複数のスクリプトを動作させており、どれが最初に実行されているのかは気にしまっせん。Inputをリセットし続ける場合は、それを他の場所で見逃します。

さて、アニメーションがいかに適用されるのかを見てください。“idle(動いていない場合)”を除き、現在のアニメーションがその状態でセットされ、フェイドインとなります。OKです。

元のスクリプトにおいては、動いていないアニメーションは決して状態をセットしませんが、同期化のためにそれをしたいと思います。それを加えるために、Update()において"controller.velocity.sqrMagnitude < 0.5"を見つけ、その状態をセットしてください。遠隔にあるコピーがコントロールしているユーザからその状態を取得することになるため、isControllableをチェックすべきです。

charがコントロールできるない場合は、スピードとアニメーションを適用します。変更されたアップデートの方法は以下にあります:

オリジナルなスクリプトがアニメーションスピードを速度で変更しますが、他のプレイヤーのモンスターにはそれを行うことができません。この部分をスキップし、望むアニメーションのスピードを適用してください。もっと上手にやる事も出来ますが、この今回はこれで大丈夫です。

なにか忘れていますね? characterStateを送信する予定でしたが、まだそれを行っていませんでした。NetworkCharacterをそれに応じて変更してください。

このバージョンでスタートしてみると、ついにアニメーションが同期化し、動きをスムーズになっています:

Photon Cloud Screenshot: Marco Polo

エディタ(左)がいかにトップ(右)上のスタンドアロンとして同じアニメーションを示しているかを注目してください。

もくじへ戻る

叫び、応える 

モンスターが話すことができると魅力的です。 音声を録音するか、ウェブで音声合成ソフトを探しましょう。 どちらにしろ:次のために二つのオーディオクリップを 用意してください:(www.fromtexttospeech.comからの例).

PhotonViewには、Remote Procedure Callの略で、「RPC」と呼ばれるメソッドがあります。 目的は他のメソッドを呼び出すことだけではありません。

RPCの良いところは、同じGameObject上で同ルーム内の他のクライアントにメソッドを呼ぶことです。 便宜上、クライアント「自身の」のメソッドを呼び出すこともできます。

PhotonView.RPC()メソッドは、任意のメソッドを呼び出すのではなく、PunRPCという特別な属性を持つものを呼びます。コー​​ドでは、これは[PunRPC](UnityScriptでは@PunRPC)です。

Unity 5.1は、RPC属性を旧式としているので、後に削除されることは明らかです。このため、PUN v1.56以前は`PunRPC`という別の属性を使用しています。RPCおよび「Remote Procedure Call」の他のすべての用途に影響はありません。

ローカルや他のプレイヤーのクライアントでモンスターを簡単に叫ばせるためにRPCメソッドを使用することができます。 「Marco Polo」フォルダで、別のスクリプト「AudioRpc」を作成します。 PunRPC属性を持つ「Marco」や「Polo」メソッドを追加します。 また、再生するサウンドファイルを参照することができるように、 パブリックのAudioClipフィールドを追加します。

“AudioRpc”を“monsterprefab”に加え、2つのサウンドファイルを参照ファイルに適用してください(両方の回数:ドラッグ&ドロップ。我々は、プレファブ(メインメニュー、コンポーネント、オーディオ、オーディオソース)上のオーディオソースを追加する必要もあります。

便宜上、我々はRandomMatchmaker GUIにボタンを追加し、これらによりRPCを呼び出すことができました。しかし、我々は、我々のモンスターのPhotonViewにはまだアクセスできません。我々は、モンスターが作成された時に、それをつかみ、保存することができます。そのように、RandomMatchmakerを変更してください:

様々なPhotonTargetsのオプションがあることにご留意ください。我々はサウンドをローカルにも再生するために今、“全て”を使用しています。

あなたが2つのクライアントを今、動作させており、いずれかのボタンをクリックする場合、声は微か過ぎて聞こえないかもしれません。カメラに移動するか、ラウドネスを調整すれば、エコーに気づきます。両方のクライアントが音声を再生します。“遠隔”プレイヤーには(ネットワーキングの遅延に応じて)短い遅延が発生します。

テスト中だけで使える方法ですが、バックグラウンドでRPCオーディオを無効にしましょう。アプリケーションのまとまりがつかない時はAudioRPC内のOnApplicationFocusを実行し、スクリプトを無効にしてください。そして、再度テストしてください。まだエコーがあります。

PRCは無効のスクリプト上でも呼び出されます。これは面倒なことになりえますが、大抵は、それは良いことです。もし無効スクリプト上のRPCをスキップしたい場合、Poloの部分の.enabledをチェックしてください。以下のようになります。

もくじへ戻る

“それ”を切り替える  

ここまでで、コールとアンサーは出来ました。足りていないのは誰が“それ”でるかとを知るゲームロジックと、他者へタグ付けするためのゲームロジックです。

最初のゲームロジックに対しては、C#スクリプト“GameLogic”を“Marco Polo”フォルダで作成し、それを“Scripts”オブジェクトに追加します。

ルームに入る最初のプレイヤーは、“それ”です。方法OnJoinedRoomが呼び出された時に我々がルームに入っていたことを知っており、PhotonNetwork.playerListをチェックすることにより、我々が最初なのかどうかを簡単に調べることができます。

プレイヤーのID

Photonは、ルームにいる各プレイヤーに印を付けるために“ID”または“playerNumber(プレイヤー番号)”を使います。それは整数であり、データの観点では比較的小さくしてくれます。それは再度割り当てられませんので、そのIDでルームにいるプレイヤーに関して“話す”ことができます。

ローカルのクライアントのIDはPhotonNetwork.player.IDに保存されています。プレイヤーが我々だけの場合は、これをスタティックフィールドの“playerWhoIsIt”に保存しています。"playerWhoIsIt"は様々なスクリプトから簡単にアクセス出来ます。

多くのプレイヤーが参加する時、現在誰が“それ”なのかを知らせる必要があります。新たなプレイヤーが参加した時PUNはOnPhotonPlayerConnectedを呼ぶので、それを利用して簡単に知らせる事が可能です。

我々は、“playerWhoIsIt”をセットし、それをRPCにするために、方法“TaggedPlayer”を作成しますので、ゲームにいるプレイヤーはすでにそれを呼び出ししているかもしれません。

シーンでのPhotonView

すでにRPC方法を準備しましたが、スクリプトがPhotonViewでGameObjectに追加されなければ、それを呼び出すことができません。理論的には、誰が“それ”なのかを覚えておくのはモンスターの仕事ではありませんので、別のPhotonViewを追加しましょう。

今回は、シーン内の「Script」オブジェクトにPhotonViewを追加します。シーンの階層構造の一部なので、所有者は「Scene」になります。これは見つけるのが簡単で任意のプレーヤーにも利用できます。GameLogicとPhotonViewは同じGameObjectにあるので、シーンのPhotonViewをGetComponentし、その上でRPCを呼び出すことができます。

一人のプレイヤーが新しいプレイヤーを更新するだけで十分です。Unity Networkingのようにホストはありませんが、PUNにはその代わりがあります。「Master Client」は常にルーム内で最も低いIDを持つプレイヤーです。 クライアントは、PhotonNetwork.isMasterClientを使用して、現在のマスターであるかどうかを確認できます。

GameLogicスクリプトにOnPhotonPlayerConnected()および静的メソッド「TagPlayer 」を追加します。後者は、どこからでも簡単に呼び出すことができます。後で必要になります。この部分は、以下のようになります:

取り残される

プレイヤーはいつでも退出可能であり、おそらく、“求めている”プレイヤーをこのようにして失います。

PUNは、誰かが退出したときに、OnPhotonPlayerDisconnectedを呼び出します。退出したプレイヤーが“それ”かどうかを見つけ出し、新たな者に割り当てるべきです。再度、この作業は1人のプレイヤーであるマスターによってのみ行われます。

ヒットされる

他者をタグ付けする方法が必要となります。コライダーから無関係に、プレイヤーが別のモンスターをクリックするかどうかを単にチェックします。このクリックされたモンスターが"それ"になります。

“Marco Polo”フォルダに新たなC#スクリプト“ClickDetector”を作成し、それを“monsterprefab”にドラックします。その中で、それがこのプレイヤーの番であるかどうかをマウスクリックでチェックするために、アップデートの方法を使います。クリックされたオブジェクト(あるとすれば)を取得し、それは平面ではないか、我々のモンスターではないことを確認します。

何がクリックされたことを知ると、そのPhotonViewを得ます。その代わりに、これでどのプレイヤーにモンスターが属しているかが分かりますので、タグ付けするためにそのプレイヤーIDを使うことができます。

スタティックTagPlayerメソッドを使用すると、別のプレイヤーをタグ付けするのがとても簡単になります。

“Marco”と“Polo”に対するGUIボタンは、どのプレイヤーに対してもまだ両方示されます。これは“playerWhoIsIt”をチェックすることでも簡単に変更可能です。我々は“Marco”のみを示し、我々は“それ”です。RandomMatchmakerはそのように変更すべきです:

もくじへ戻る

結論

今、簡単なゲームの小さなプロトタイプが完成しました。確かに、多くの要素が抜けていますが基本は確実に網羅しました。我々のゲームはランダムのルームでプレイヤーを見つけ、ポジションを同期化し、動きをスムーズにし、それに加え、基本のゲームロジックがあります。プレイヤーIDと“Master Client(マスタークライアント)”を使用し、PUN ネットワーキングメッセージ及びその他を実行することを学びました。

“それ”ではないプレイヤーを隠すこと、“attack(攻撃)”アニメーションをRPCと同期、または誰かがただタグ付けされた後に次のタグ付けを遅らせることは、もはやそれほどこわいことではないようです。また、我々のキャラクターをコントロールする方法が分かったので、同じ形でカメラをコントロールすることはもはやそれほど難し事ではありません。

あなたのモンスターを解き放ってください!:)

 ドキュメントトップへ