Skip to content

201 2 Photonとの接続

miuccie miurror edited this page Jan 30, 2019 · 47 revisions

201-1 - Photonとの接続

ここからは、前項で確認したシングルプレーヤーシーンに、Photonエンジンを組み込んだマルチプレーヤー対応を実装していきます。


PUNのインストール

下記のリンクよりUnityのアセットストアを開いて、PUN2 Freeをプロジェクトにインポートします https://assetstore.unity.com/packages/tools/network/pun-2-free-119922

Photonクラウドのセットアップ

最初にAppIdを登録して、Photonクラウドを使用できるようにします。 AppIdはPhotonのサイトから取得可能です。同時接続20人までのプランであれば無料で始めることができます。 https://dashboard.photonengine.com/ja-JP/publiccloud

適当な名前でアプリケーションを登録して、AppIdを取得したら、Unityの画面上部のメニューから、Window/Photon Unity Networking/PUN Wizard/LocatePhotonServerSettingsを開き、AppId Realtimeに取得したAppIdを設定します。

PUN2では、その他の設定はまずはデフォルトのままで大丈夫です。特にリージョンはPUN2以降は特に指定がない限り自動で近場のリージョンが設定されるようになりました。


ログイン処理

まずはPhotonクラウドと接続してルームへログインしなければなりません。 Photonでは、まずマスターサーバーへ接続した後、ルームの集合体であるロビーへログインし、 参加するルームをルーム名で指定 or まだルームが存在しなければ自分で作成してログインします。

PUN2では特に必要がない場合、ロビーを使用することは非推奨となりました。

ログイン関連の通信を行うには、PhotonNetworkクラスを使用します。

PhotonNetworkリファレンス
https://doc-api.photonengine.com/en/pun/v2/class_photon_1_1_pun_1_1_photon_network.html

またPhotonクラウドとの入室時の一連のやりとりは、PUNが発行するイベントを受信するコールバックを定義することで行います。これらのイベントはどのクラスからも受信することが可能です。

PUN2では、主要なコールバックはインタフェースとして定義するように変更されました。ルーム関連のコールバックは、IMatchmakingCallbacks とIInRoomCallbacksインタフェースに定義されています。 受信したいイベントに対応するハンドラを実装することで自動的に呼び出されますが、よく使用されるコールバックはMonoBehaviourPunCallbacksクラスにメソッドとして実装されているので、ひとまずはこれを継承し、必要なものだけをoverrideして使用します。

ルーム関連のイベントコールバック一覧
https://doc-api.photonengine.com/en/pun/v2/class_photon_1_1_pun_1_1_mono_behaviour_pun_callbacks.html
https://doc-api.photonengine.com/en/pun/v2/interface_photon_1_1_realtime_1_1_i_matchmaking_callbacks.html
https://doc-api.photonengine.com/en/pun/v2/interface_photon_1_1_realtime_1_1_i_in_room_callbacks.html


それではルームへのログインを実装してみましょう。 ステージ上にPhotonという名前の空のGameObjectを作成し、下記の内容で作成したPhotonLogin.csというスクリプトをアタッチしてください。

using UnityEngine;
using System.Collections;

using Photon.Pun;
using Photon.Realtime;

namespace VRStudies { namespace SinglePlayer {

public class PhotonLogin : MonoBehaviourPunCallbacks {

	static string GAME_VERSION = "Ver.1";

	static RoomOptions ROOM_OPTIONS = new RoomOptions() {
		MaxPlayers = 20,
		IsOpen = true,
		IsVisible = true
	};

	//------------------------------------------------------------------------------------------------------------------------------//
	void Start() {

		// アプリの起動と同時にPhotonCloudに接続
		Debug.Log("PhotonLogin: マスターサーバーに接続します");
		PhotonNetwork.GameVersion = GAME_VERSION;
		PhotonNetwork.ConnectUsingSettings();
	}

	public override void OnConnectedToMaster() {

		Debug.Log("PhotonLogin: マスターサーバーに接続しました");
		Debug.Log("PhotonLogin: ルームに入室します");

		// ルームへの参加 or 新規作成
		PhotonNetwork.JoinOrCreateRoom("VR-Room", ROOM_OPTIONS, null);
	}

	//------------------------------------------------------------------------------------------------------------------------------//
	public override void OnJoinedRoom() {

		Room room = PhotonNetwork.CurrentRoom;
		Photon.Realtime.Player player = PhotonNetwork.LocalPlayer;
		Debug.Log("PhotonLogin: ルーム入室に成功 - " +  room.Name);
		Debug.Log("PhotonLogin: プレイヤー情報: " +  " プレイヤーNo: "  + player.ActorNumber + " ユーザーID: " + player.UserId + " ルームマスター: " + player.IsMasterClient);
		Debug.Log("PhotonLogin: ルーム情報: " + room);
	}

	public override void OnJoinRandomFailed(short returnCode, string message) {
		Debug.Log("PhotonManager: ルーム入室に失敗. ルームを新規作成します");
		PhotonNetwork.CreateRoom(null, ROOM_OPTIONS);
	}

	public override void OnCreateRoomFailed(short returnCode, string message) {
		Debug.Log("PhotonLogin: ルーム作成に失敗");
	}
}
}}

ここで下記の2つのネームスペースをimportしていることに注意してください。

using Photon.Pun; //PUNの基本クラスがまとめられたパッケージ
using Photon.Realtime; //PUNの拡張機能などがまとめられたパッケージ

またPhotonLoginは、MonoBehaviourPunCallbacksを継承している点に注意してください。この親クラスの中で実装されているコールバックのうち、必要なものをoverrideすることで、ルーム入室時の各種イベントを拾っています。

PhotonNetwork.ConnectUsingSettings()によってPhotonのマスターサーバーへ接続する際には、ゲームバージョンを指定できます。ここで渡した文字列によって、同一AppID内であってもログインするオンライン空間のバージョンを分けることができます。また実際のルーム作成時には、同時接続人数などの細かいオプションを渡すことが可能です。

ルームオプション一覧
https://doc-api.photonengine.com/en/pun/current/class_room_options.html


接続状況の出力

さらに今後の開発を容易にするために、Photonとの接続状況がゲーム画面に出力されるようにします。 下記の内容でPhotonStatus.csという名前のスクリプトを作成し、これをPhotonオブジェクトにアタッチしてください。

using UnityEngine;
using System.Collections;

using Photon.Pun;
using Photon.Realtime;

namespace VRStudies { namespace SinglePlayer {

public class PhotonStatus : MonoBehaviour {

	//------------------------------------------------------------------------------------------------------------------------------//
	void OnGUI () {

		// Photonとの接続状況を表示する
		string status = "Photon: " + PhotonNetwork.NetworkClientState.ToString() + "\n";

		// ルームに入室したら部屋の状況を表示する
		if( PhotonNetwork.InRoom ){
			status += "-------------------------------------------------------\n";
			status += "Room Name: " + PhotonNetwork.CurrentRoom.Name + "\n";
			status += "Player Num: " + PhotonNetwork.CurrentRoom.PlayerCount + "\n";
			status += "-------------------------------------------------------\n";
			status += "Player No: " + PhotonNetwork.LocalPlayer.ActorNumber + "\n";
			status += "IsMasterClient: " + PhotonNetwork.IsMasterClient;
		}

		GUI.TextField( new Rect(10, 10, 220, 120), status);
	}
}
}}

ログインの確認

ここまでのシーンをUnity上で実行してみてください。画面左上に接続ステータスが表示され、最終的にJoinedという接続メッセージとルームの情報が表示されればログイン成功です。


講義で実装したマルチプレーヤー対応は下記シーンにまとめて収められています
https://github.com/yumemi-inc/vr-studies/tree/master/vol2/VR-studies/Assets/VR-studies/1_MultiPlayer/MultiPlayer.unity


TIPS: 複数クライアントの起動方法

マルチプレーヤープログラムをローカルでテストするためには、複数のクライアントをひとつのPC内で起動できるようにしなくてはなりません。

Unityでこれを行う方法としてはいくつか考えられます。

  1. Unityでビルドしたappを複数起動する
  2. UnityでビルドしたappとUnityエディタ内実行を併用する
  3. Unity自体を複数起動可能にし、同一のプロジェクトを開く

このうち、開発環境として理想なのは、3.のUnity自体を複数起動して同一のプロジェクトを開くことなのですが、これを現行のUnityで行うためには、WindowsでもMacでも独自の工夫が必要になってきます。

ここでは比較的手軽にテスト・デバッグ可能な、2.のビルドしたappとエディタの同時実行をおすすめします。