今回はPhotonCloudに接続し、部屋を作成したり既存の部屋に入室したり退室したりする機能を作成していきます。
ログインしたらネットワークに接続するスクリプトの作成とUIを作成していきます。
前回は
PhotonCloudのアカウントを作成し、Unityで設定をするところまでをやりました。
まだ登録してない方は↑の記事をご覧いただき登録と設定をすませてください。
C#とJavaScriptの連携
まず最初に把握しておかなければいけない事があります。
それはAssetStoreからインポートしたPhoton Unity NetworkingのコンポーネントのスクリプトがC#で書かれている点です。
その為JavaScriptで書いたスクリプトからC#で書かれたスクリプトを参照しようとすると定義されていませんというエラーが発生します。
C#からJavaScriptを呼び出す場合はStandardAssetsまたはPluginsフォルダの下にJavaScriptファイルを置く
[Unity] JavaScriptとC#間のアクセス: ものづくりログJavaScriptとC#間のアクセス,ものづくりの中で、気づいたこととかメモとか。
↑のサイトを参考にさせて頂き、キャラクター操作スクリプト等JavaScriptで書いた物はPluginsフォルダにScriptsフォルダを作りその中に入れるようにします。
さらにPhotonCloudを使ってネットワーク上で他のプレイヤーにメソッドを実行させる時にも問題が出るので本来のネットワーク接続とは別の勉強が必要になります。
わたくしは解決出来なかったので全部C#で書くことにしました・・・・・(-_-)
ネットワークへの接続に関して
ネットワークに接続するとマスターサーバと呼ばれるこのゲームのネットワークに接続しているサーバに接続します。
ネットワークにはロビーがありそこに部屋を複数作り、プレイヤーが部屋を選択してその部屋に入れるようにします。
つまり複数の部屋がサーバに接続されているわけですね。
例えば、マスターサーバが1つの学校だとしたら、校舎の一角がロビーで教室が部屋となります。
部屋の設定は自分で変更する事が出来て、部屋一覧として表示しない設定や部屋に入れる人数も設定出来ます。
詳しく見てないんですが、ロビーも複数作れるかも?
ネットワークに接続する為のUIを作成
ゲームをネットワークに接続する為の画面を作成していきます。
ヒエラルキーで右クリック→UI→Canvasを選択し名前をUIと変更します。
ログインUIの作成
UIの子要素にUI→Panelを作成し名前をLoginUIとします。
LoginUIのAnchor Presetsでstretch、stretchにします。
LoginUIの子要素にはネットワークにログインする時に使用する部屋選択のRoomList(Dropdown)、新しい部屋名を入力する為のRoomName(InputField)、PlayerName(InputField)、LoginButton(Button)を作成します。
それぞれのUIのタイトルを別個Textとして作成し設置します。
RoomListにはすでに存在している部屋のリストをドロップダウン形式で表示しプレイヤーが部屋を選択する事が出来るようにします。
RoomListのOptionsには最初からOptionA、OptionB、OptionCと設定されていますが、これを全部削除しておきます。
RoomNameには新しく部屋を作成する時に使用する部屋の名前を入力出来るようにしています。
PlayerNameにはデフォルトのキャラクターの名前を入力しておきます。
LoginButtonは押すとネットワークに接続処理をするスクリプトを実行するようにします。
ログアウトボタンの作成
UIの子要素にUI→Buttonを作成し名前をLogoutButtonとします。
LogoutButtonのAnchor Presetでtop、leftとします。
LogoutButtonを押した時に部屋から退出するようにします。
ネットワークへの接続状態を表示するUIの作成
UIの子要素にUI→Textを作成し名前をInformationとします。
Informationにはネットワークとの接続状態を表示するようにします。
ログイン、ログアウトのUIが完成
作成したUIの階層は
↑のようになりました。
出来た実際の画面は
↑のようになりました。
とりあえずUIを作成してみたというだけでデザイン的なものは置いておきます・・・・(-_-)
ネットワークの接続を管理するNetworkManagerスクリプトの作成
UIの作成が終了したのでネットワーク接続に関するスクリプトを書いていきましょう。
Photon Unity Networking関連のスクリプトはC#で書かれていますので、さきほど言及したスクリプト間の連携が必要になります。
そこでネットワーク接続を管理する自前のスクリプトはJavaScriptではなくC#で書いていこうと思います。
ヒエラルキー上に空のゲームオブジェクトを作成し、名前をNetworkManagerとします。
NetworkManagerゲームオブジェクトに新しくNetworkManagerスクリプトを作成し取りつけます。
今回はスクリプトの処理を追加していく形で説明していきます。
NetworkManagerスクリプトにどんどん追加していってください。
スクリプト開始時の処理
まずはNetworkManagerスクリプト開始時の処理を追加します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | public class NetworkManager : Photon.PunBehaviour { // Use this for initialization void Start () { // ログをすべて表示する PhotonNetwork.logLevel = PhotonLogLevel.Full; // ロビーに自動で入る PhotonNetwork.autoJoinLobby = true; // ゲームのバージョン設定 PhotonNetwork.ConnectUsingSettings ("0.1"); } } |
PhotonNetwork.logLevelはネットワークに接続した時のログの表示設定です。
今回はPhotonLogLevel.Fullを入れ全てのログを表示するようにしています。
PhotonNetwork.autoJoinLobbyの設定をtrueにし、マスターサーバに接続出来た時は自動でロビーに入室するようにします。
部屋の選択をせず自動で部屋に入室するように作る場合はfalseにしてロビーに入らなくてもいいようにします。
PhotonNetwork.ConnectUsingSettingsはゲームのバージョンを設定してネットワークに接続します。
自身のゲームのバージョンを設定します。
ネットワークへの接続状態を表示
次にネットワークへの接続状態を表示します。
1 2 3 4 5 6 7 8 9 10 11 | // ログインまでの情報を表示するテキスト [SerializeField] private Text informationText; // Update is called once per frame void Update () { // サーバ接続状態を表示 informationText.text = PhotonNetwork.connectionStateDetailed.ToString(); } |
ネットワーク接続の状態を表示するinformationTextフィールドを宣言し、インスペクタでInformationのテキストをドラッグ&ドロップします。
Update関数内でPhotonNetwork.connectionStateDetailedを使ってネットワーク接続の状態を表示しています。
これは単に現在どの状態かを自分で確認する為に表示しているだけなのであえて表示しなくてもいいです。
マスターサーバに接続、ロビーに入った時の処理
次はマスターサーバに無事接続された時の処理とロビーに入った時の処理です。
1 2 3 4 5 6 7 8 9 10 11 | // ログイン画面 [SerializeField] private GameObject loginUI; // ロビーに入った時に呼ばれる public override void OnJoinedLobby() { Debug.Log("ロビーに入る"); loginUI.SetActive(true); } |
loginUIにはインスペクタでLoginUIゲームオブジェクトを設定します。
OnJoinedLobbyはロビーに入った時に呼ばれるメソッドです。
Startメソッド内で自動でロビーに入る設定にしている為、マスターサーバに接続されるとそのままロビーに入ります。
ロビーに入ったらログイン用のUIをアクティブにし、ログイン画面を表示します。
LoginUIゲームオブジェクトは非アクティブにしておきスクリプトからアクティブにするようにします。
LoginButtonを押した時に実行するメソッド
次にLoginButtonボタンを押した時に実行するメソッドを記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | // 部屋リストを表示するドロップダウン [SerializeField] private Dropdown roomLists; // 部屋の名前 [SerializeField] private InputField roomName; // ログインボタンを押した時に実行するメソッド public void LoginGame() { // ルームオプションを設定 RoomOptions ro = new RoomOptions() { // ルームを見えるようにする IsVisible = true, // 部屋の入室最大人数 MaxPlayers = 10 }; if (roomName.text != "") { // 部屋がない場合は作って入室 PhotonNetwork.JoinOrCreateRoom(roomName.text, ro, TypedLobby.Default); } else { // 部屋が存在すれば if (roomLists.options.Count != 0) { Debug.Log(roomLists.options[roomLists.value].text); PhotonNetwork.JoinRoom(roomLists.options[roomLists.value].text); // 部屋が存在しなければDefaultRoomという名前で部屋を作成 } else { PhotonNetwork.JoinOrCreateRoom("DefaultRoom", ro, TypedLobby.Default); } } } |
RoomOptionsをインスタンス化し部屋の設定をします。
IsVisibleをtrueにするとこの部屋が可視化され見えるようになります。falseにすると不可視になり秘密の部屋を作成したい時に便利かもしれません。
MaxPlayersはこの部屋に入室出来る最大人数でこれ以上の人数が入室しようとしたらエラーが発生するのでそれ用の処理も必要になってきます。
今回のサンプルの仕様では
1.部屋の名前(RoomName)に部屋の名前を入力していればその名前で部屋を作成し入室します。
2.部屋の名前(RoomName)に何も入力されていなければドロップダウンリストに他の部屋があれば選択している部屋に入室します。
3.ドロップダウンリストに他の部屋がなければDefaultRoomという名前の部屋を作成し入室します。
↑という流れにしていて、
自分で作成した部屋を作る→既存の部屋に入室→DefaultRoomという名前の部屋を作成し入室
条件に合致しなければ次の処理を実行する感じになります。
JoinOrCreateRoomは部屋の名前を指定し存在していればその部屋に入室、存在しなければその名前の部屋を作成し入室します。
部屋のオプションro、ロビーはデフォルトのロビーにします。
JoinRoomはその名前の部屋に入室します。
LoginButtonのOn ClickにNetworkManagerゲームオブジェクトをドラッグ&ドロップし、LoginGameメソッドを実行するようにしましょう。
↑のようにインスペクタで設定しました。
部屋情報が更新された時の処理
次にロビーに追加された部屋の情報を更新しドロップダウンリストに表示する処理を記述していきます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | // 部屋が更新された時の処理 public override void OnReceivedRoomListUpdate() { Debug.Log("部屋更新"); // 部屋情報を取得する RoomInfo[] rooms = PhotonNetwork.GetRoomList(); // ドロップダウンリストに追加する文字列用のリストを作成 List<string> list = new List<string>(); // 部屋情報を部屋リストに表示 foreach (RoomInfo room in rooms) { // 部屋が満員でなければ追加 if (room.PlayerCount < room.MaxPlayers) { list.Add(room.Name); } } // ドロップダウンリストをリセット roomLists.ClearOptions(); // 部屋が1つでもあればドロップダウンリストに追加 if (list.Count != 0) { roomLists.AddOptions(list); } } |
部屋情報が更新されるとOnReceivedRoomListUpdateメソッドが呼ばれるのでそこでPhotonNetwork.GetRoomListを使って部屋情報を取得します。
部屋情報をforeachで1つ1つ取得し部屋の定員を超えていなければリストに追加します。
最後に部屋情報が1つでもあればドロップダウンリストのAddOptionsを使ってドロップダウンリストの項目に部屋名を足しています。
部屋に入室成功、失敗した時の処理
次は部屋への入室に成功した時と失敗した時の処理です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | // ログアウトボタン [SerializeField] private GameObject logoutButton; // プレイヤーの名前入力欄 [SerializeField] private InputField playerName; // 部屋に入室した時に呼ばれるメソッド public override void OnJoinedRoom() { loginUI.SetActive (false); logoutUI.SetActive (true); Debug.Log ("入室"); // InputFieldに入力した名前を設定 PhotonNetwork.player.NickName = playerName.text; } // 部屋の入室に失敗した void OnPhotonJoinRoomFailed() { Debug.Log("入室に失敗"); // ルームオプションを設定 RoomOptions ro = new RoomOptions() { // ルームを見えるようにする IsVisible = false, // 部屋の入室最大人数 MaxPlayers = 10 }; // 入室に失敗したらDefaultRoomを作成し入室 PhotonNetwork.JoinOrCreateRoom("DefaultRoom", ro, TypedLobby.Default); } |
部屋に入室したらOnJoinedRoomメソッドが呼ばれます。
そこでLoginUIを非表示、LogoutButtonを表示するようにします。
入室に成功したらプレイヤーの名前をネットワークのニックネームに設定します。
部屋の入室に失敗したらOnPhotonJoinRoomFailedメソッドが呼ばれます。
入室に失敗する理由としては部屋がそもそも存在しないのに入室しようとしたり、部屋の定員が超えているのに入室した時等があります。
そこでPhotonNetwork.JoinOrCreateRoomを使って入室出来るようにします。
LogoutButtonを押した時の処理
次にLogoutButtonを押した時の処理を記述していきます。
1 2 3 4 5 6 7 8 9 10 11 12 | // ログアウトボタンを押した時の処理 public void LogoutGame() { PhotonNetwork.LeaveRoom (); } // 部屋を退室した時の処理 public override void OnLeftRoom() { Debug.Log("退室"); logoutButton.SetActive(false); } |
ログアウトボタンを押したらPhotonNetwork.LeaveRoomを使って部屋から退室させます。
OnLeftRoomメソッドは部屋から退室すると呼ばれるメソッドなのでそこでLogoutButtonを非表示にしてます。
↑のようにLogoutButtonのインスペクタでOn ClickにNetworkManagerのLogoutGameを実行するように設定します。
これで簡易ではありますがネットワーク接続の処理が完成しました。
ネットワーク接続を確認する
ネットワーク接続処理が完成したので、設定をします。
ログイン画面UIとログアウトボタンはスクリプトでオン・オフしていきますので、最初は↑のように非表示にしておきます。
NetworkManagerのインスペクタのNetworkManagerスクリプトの設定は↑のように設定します。
設定が終わったので、ビルドしたあとにアプリケーションを実行しログインしてみましょう。
アプリケーションを複数実行し部屋を作成したり、既存の部屋を選んで入室したりしてみてください。
まだネットワークに接続してもキャラクター等は登場させていないのでわかり辛いですが、部屋を選択しログインボタンを押すと同じ部屋にログインするので、
同じゲームの世界に複数の人が接続している状態になります。
今回はネットワークに接続し、部屋を作り入室、退室するまでの処理を記述しました。
今回作成したUIだと非常に不便で、部屋リストと新しく部屋を作る画面が一緒になっています。
まぁそこら辺は本来の機能とは別の部分なので不便さは無視してください・・・・・(+_+)
今回のようにネットワークに接続する処理は慣れていないと難しく感じますね・・・・(^_^;)
でもPhotonCloudのPUNを使っているので本当に難しい処理は考慮しなくてすんでいます(^_^)v
パンチスルーとはなんだあああああああああああって事にならなくて済みますからね・・・・。
次回はログインした人のキャラクターをゲームの世界に登場させる処理を作成していきます。
参考サイト
Photon Networkの処理についてはこちらを見るとよくわかります。
PhotonCloudを使ったネットワーク処理に関してはUnityのライブトレーニングが非常に参考になります。