Photon Unity Networking の Room作成のScriptパターン研究

Unityで[Photon Unity Networking](https://www.photonengine.com/ja/PUN)を使う時に、Roomを作成するScriptを書くのですが、それについて考察します。

# Room作成の基本スクリプト

Room作成Scriptに必須な事項をまとめた。しかし、このScriptを書くだけでは、Roomが生成されないため、何も起きないので注意。
忘れてはいけないポイントは

1. Photon.MonoBehaviourの継承
2. `PhotonNetwork.ConnectUsingSettings("0.1");`をStartメソッドに書く
3. Roomに参加した時に `PhotonNetwork.Instantiate()`でPlayerを生成する

である。

```csharp:RoomManager.cs
using UnityEngine;

// ポイント1 : Photon.MonoBehaviourの継承を忘れずに
public class RoomManager : Photon.MonoBehaviour {
    
    void Start() {
        // ポイント2: サーバーに接続する。引数は0.1でよい
        // サーバー接続に成功した後は自動でLobbyに参加する
        PhotonNetwork.ConnectUsingSettings("0.1");
    }

    // Roomに参加するのに成功した時に呼ばれる
    void OnJoinedRoom() {
        PlayerMake();
    }
    
    // ポイント3: Playerを生成するメソッド
    void PlayerMake(){
        // Resourcesフォルダに入っている"Player"という名前のオブジェクトを生成する。
        // 第一引数がGameObject型ではなくString型であることに注意
        PhotonNetwork.Instantiate("Player", Vector3.zero, Quaternion.identity, 0);
        
    }

    // ゲームには不要だが、接続状態を確認できるので、製作途中では重宝する
    void OnGUI() {
        GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString());
    }
}
```

# Roomは1つ、全員1つのRoomに自動で入る

困ったらこの書き方でOKです。
以下の様な二つのメソッドを追加する。

```csharp:追加するメソッド
// Lobbyに参加した時に呼ばれる
    void OnJoinedLobby() {
       //すでに存在しているRoomにランダムに入る
		PhotonNetwork.JoinRandomRoom();
    }

    // ランダムにRoomに参加するのに失敗した時に呼ばれる
    void OnPhotonRandomJoinFailed() {
        //Roomを自分で作って参加する
		PhotonNetwork.CreateRoom(null);
    }

```

全体のスクリプトは下のようになる。

```csharp:RoomManager2.cs
using UnityEngine;

// ポイント1 : Photon.MonoBehaviourの継承を忘れずに
public class RoomManager : Photon.MonoBehaviour {
    
    void Start() {
        // ポイント2: サーバーに接続する。引数は0.1でよい
        // サーバー接続に成功した後は自動でLobbyに参加する
        PhotonNetwork.ConnectUsingSettings("0.1");
    }
    // Lobbyに参加した時に呼ばれる
    void OnJoinedLobby() {
       //すでに存在しているRoomにランダムに入る
		PhotonNetwork.JoinRandomRoom();
    }

    // ランダムにRoomに参加するのに失敗した時に呼ばれる
    void OnPhotonRandomJoinFailed() {
        //Roomを自分で作って参加する
		PhotonNetwork.CreateRoom(null);
    }

    // Roomに参加するのに成功した時に呼ばれる
    void OnJoinedRoom() {
        PlayerMake();
    }
    
    // ポイント3: Playerを生成するメソッド
    void PlayerMake(){
        // Resourcesフォルダに入っている"Player"という名前のオブジェクトを生成する。
        // 第一引数がGameObject型ではなくString型であることに注意
        PhotonNetwork.Instantiate("Player", Vector3.zero, Quaternion.identity, 0);
        
    }

    // ゲームには不要だが、接続状態を確認できるので、製作途中では重宝する
    void OnGUI() {
        GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString());
    }
}
```

# Roomは1つ、スペースキーを押した時にRoomに入る

OnJoinedLobbyメソッドの中身を、Updateメソッドの中のif文の中に書き換える。

```csharp:RoomManager3.cs

using UnityEngine;

// ポイント1 : Photon.MonoBehaviourの継承を忘れずに
public class RoomManager : Photon.MonoBehaviour {
    
    void Start() {
        // ポイント2: サーバーに接続する。引数は0.1でよい
        // サーバー接続に成功した後は自動でLobbyに参加する
        PhotonNetwork.ConnectUsingSettings("0.1");
    }
    // Updateメソッド
    void Update(){
        // スペースキーを押したら
        if(Input.GetKeyDown(KeyCode.Space)){
            //Lobbyの中にいたら
	        if(PhotonNetwork.insideLobby){
                //すでに存在しているRoomにランダムに入る
                PhotonNetwork.JoinRandomRoom();  
            }          
        }
    }

    // ランダムにRoomに参加するのに失敗した時に呼ばれる
    void OnPhotonRandomJoinFailed() {
        //Roomを自分で作って参加する
		PhotonNetwork.CreateRoom(null);
    }

    // Roomに参加するのに成功した時に呼ばれる
    void OnJoinedRoom() {
        PlayerMake();
    }
    
    // ポイント3: Playerを生成するメソッド
    void PlayerMake(){
        // Resourcesフォルダに入っている"Player"という名前のオブジェクトを生成する。
        // 第一引数がGameObject型ではなくString型であることに注意
        PhotonNetwork.Instantiate("Player", Vector3.zero, Quaternion.identity, 0);
        
    }

    // ゲームには不要だが、接続状態を確認できるので、製作途中では重宝する
    void OnGUI() {
        GUILayout.Label(PhotonNetwork.connectionStateDetailed.ToString());
    }
}
```