Photon2で下画像のようなルームリストを作りたい
前回の続きになります。
前回:[Unity,Photon2]Photon2でルームを作成したい
こんな感じで選択したボタンを押したらそのルームに入りたい。
今回はそのボタンを作成します。
表示させるボタン
今回使ったボタンのプレハブの構成はこんな感じです。
ボタンには押されたらボタンの中で表示されているRoomNameのルームに移動するという処理だけです。
調べたらいくらでも出てくるので割愛。
ボタンを生成、情報を入力
今回はボタンを並べたかったのでScroolView内のContentにボタンを生成します。
デフォルトから名前を変更した"RoomContet"に"ViewMatchWaitingPlayers.cs"というスクリプトを追加します。
ViewMatchWaitingPlayers.csの構成
usingSystem.Collections.Generic;usingUnityEngine;usingPhoton.Pun;usingPhoton.Realtime;usingUnityEngine.UI;publicclassViewMatchWaitingPlayers:MonoBehaviourPunCallbacks{publicGameObjectRoomButton;publicvoidStart(){//ロビーへ移動するPhotonNetwork.JoinLobby();}//ルームに動きがあった場合publicoverridevoidOnRoomListUpdate(List<RoomInfo>roomList){Debug.Log("[function]ReloadRooms");foreach(RoomInforinroomList){//プレイヤーが存在しているルームif(r.PlayerCount>0){RoomButtonCreate(r);}else{RoomButtonDelete(r);}}}//ルームボタンの作成publicvoidRoomButtonCreate(RoomInfor){//すでに存在していたのなら情報の更新if(gameObject.transform.Find(r.Name)){RoomInfoUpdate(gameObject.transform.Find(r.Name).gameObject,r);}//新しく作られたルームならばボタンの作成else{varroomButton=(GameObject)Instantiate(RoomButton);roomButton.transform.SetParent(gameObject.transform,false);RoomInfoUpdate(roomButton,r);//生成したボタンの名前を作成するルームの名前にするroomButton.name=r.Name;}}//ルームボタンの削除publicvoidRoomButtonDelete(RoomInfor){//ボタンが存在すれば削除if(gameObject.transform.Find(r.Name)){GameObject.Destroy(gameObject.transform.Find(r.Name).gameObject);}}//ルームボタンのInfoの更新publicvoidRoomInfoUpdate(GameObjectbutton,RoomInfoinfo){foreach(Texttinbutton.GetComponentsInChildren<Text>()){if(t.name=="RoomName"){t.text=info.Name;}elseif(t.name=="MaxPLayerCount"){t.text=info.MaxPlayers.ToString();}elseif(t.name=="RoomInPlayerCount"){t.text=info.PlayerCount.ToString();}}}}
このコードの簡単な解説です
ルームの取得方法
publicGameObjectRoomButton;publicvoidStart(){//ロビーへ移動するPhotonNetwork.JoinLobby();}
public GameObjectで先ほど作成しておいたボタンのプレハブを指定します。
ロビーにいないとルーム情報を取得できないのでロビーに入っておきます。
publicoverridevoidOnRoomListUpdate(List<RoomInfo>roomList){foreach(RoomInforinroomList){//プレイヤーが存在しているルームif(r.PlayerCount>0){RoomButtonCreate(r);}else{RoomButtonDelete(r);}}}
この"OnRoomListUpdate()"でルーム情報を取得します。
自分はここで詰まってたのですが、この関数はルーム内で人数が変更されたり、ルームの情報が変更されたときのみ、
変更が起こったルームだけroomListに入ります。
任意のタイミングでは実行できません。
ルームのリスト全部じゃないんかーい。好きなタイミングで呼び出せんのかーいって感じですが、仕様ならしょうがないです。
ちなみに、
ロビーに入ったときは何もない状態から"OnRoomListUpdate"を読み込む形になるのでルームが存在すればすべてのルームがroomListに入ります。
それ以降は先ほどと同じで人数が変わったなどの変更があったルームだけがroomListとして"OnRoomListUpdate()"が実行されます。
とりあえずこれでルームが取得できました。次はこのルーム情報をもとにプレハブのボタンに情報を表示させてボタンを生成していきます。
ルーム情報を可視化
"OnRoomListUpdate()"で更新があったルームリストがくるので、
そのリストの中のルームにプレイヤーがいる = 人数制限だとしても表示させるとしたら表示する。
なので、
プレイヤーが存在していたらボタンを作成していく方向で行きます。
publicvoidRoomButtonCreate(RoomInfor){//すでに存在していたのなら情報の更新if(gameObject.transform.Find(r.Name)){RoomInfoUpdate(gameObject.transform.Find(r.Name).gameObject,r);}//新しく作られたルームならばボタンの作成else{varroomButton=(GameObject)Instantiate(RoomButton);roomButton.transform.SetParent(gameObject.transform,false);RoomInfoUpdate(roomButton,r);//生成したボタンの名前を作成するルームの名前にするroomButton.name=r.Name;}}publicvoidRoomInfoUpdate(GameObjectbutton,RoomInfoinfo){foreach(Texttinbutton.GetComponentsInChildren<Text>()){if(t.name=="RoomName"){t.text=info.Name;}elseif(t.name=="MaxPLayerCount"){t.text=info.MaxPlayers.ToString();}elseif(t.name=="RoomInPlayerCount"){t.text=info.PlayerCount.ToString();}}}
ルームの情報が更新されるたびに"OnRoomListUpdate()"が実行されるので
すでに存在しているルームならば情報の更新だけにしておきます。そうしないと人が抜けたり入ったりするだけで同じルームのボタンがいくつも生成されてしまいます。
これで生成したボタンに情報が入るようになります。
ルームが消えたらルームのボタンを消す
publicvoidRoomButtonDelete(RoomInfor){//ボタンが存在すれば削除if(gameObject.transform.Find(r.Name)){GameObject.Destroy(gameObject.transform.Find(r.Name).gameObject);}}
人がいないルームをいつまでも表示させておくわけにはいかないので人が0人になったらボタンのリストから削除します。
おわり
ルーム情報の取得はpublic override void OnRoomListUpdate(List roomList)
public override void OnRoomListUpdate(List roomList)を使うためにはロビーに入っておく
roomListには変更があったルームの情報しか入らない