オンラインFPS:スコアボード機能実装
+ボタン押下でコードを確認できます!
コピペしても正しく動かない場合は
エディタでアタッチし忘れている可能性が高いです。
- GameManager
- This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters
using System.Collections; using System.Collections.Generic; using UnityEngine; using Photon.Pun; using UnityEngine.SceneManagement; using Photon.Realtime; using ExitGames.Client.Photon; //リアルタイムAPIのイベントコールバック。サーバーからのイベントと、OpRaiseEventを介してクライアントから送信されたイベントをカバーします。 //カスタムイベントを受信することができるようになる public class GameManager : MonoBehaviourPunCallbacks, IOnEventCallback { //イベントについて記載があるドキュメント //https://doc.photonengine.com/ja-jp/pun/current/gameplay/rpcsandraiseevent#_thy2n6w3gsafi04 public List<PlayerInfo> playerList = new List<PlayerInfo>();//プレイヤー情報を扱うクラスのリスト public enum EventCodes : byte//自作イベント:byteは扱うデータ(0 ~ 255) { NewPlayer,//新しいプレイヤー情報をマスターに送る ListPlayers,//全員にプレイヤー情報を共有 UpdateStat,//キルデス数の更新 } /// <summary> /// ゲームの状態 /// </summary> public enum GameState { Playing, Ending } public GameState state;//状態を格納 UIManager uiManager;//UI private List<PlayerInformation> playerInfoList = new List<PlayerInformation>();//playerinfoのリスト private void Awake() { uiManager = GameObject.FindGameObjectWithTag("UIManager").GetComponent<UIManager>();//56 } private void Start() { //ネットワーク接続されていない場合 if (!PhotonNetwork.IsConnected) { //タイトルに戻る SceneManager.LoadScene(0); } else//繋がっている場合 { //マスターにユーザー情報を発信する NewPlayerGet(PhotonNetwork.NickName); //状態をゲーム中に設定する state = GameState.Playing; } } private void Update() { //タブボタンが押されたとき if (Input.GetKeyDown(KeyCode.Tab)) { //更新しつつ開く ShowScoreboard(); } else if (Input.GetKeyUp(KeyCode.Tab))//タブボタンが上がった時 { uiManager.ChangeScoreUI(); } } //イベント発生時に呼び出される public void OnEvent(EventData photonEvent) { if (photonEvent.Code < 200)//200以上はphotonが独自のイベントを使っているため200以下のみに処理をする { EventCodes eventCode = (EventCodes)photonEvent.Code;//今回のイベントコードを格納(型変換) object[] data = (object[])photonEvent.CustomData;//インデクサーとCustomDataKeyを介して、イベントのカスタムデータにアクセスします switch (eventCode) { case EventCodes.NewPlayer://発生したイベントがNewPlayerなら NewPlayerSet(data);//マスターに新規ユーザー情報処理させる break; case EventCodes.ListPlayers: ListPlayersSet(data);//ユーザー情報を共有 break; case EventCodes.UpdateStat: ScoreSet(data);// break; } } } public override void OnEnable()//コンポーネントがオンになると呼ばれる { //実装されているコールバック・インターフェースのコールバック用オブジェクトを登録します。 PhotonNetwork.AddCallbackTarget(this);//追加する } public override void OnDisable()//コンポーネントがオフになると呼ばれる { PhotonNetwork.RemoveCallbackTarget(this);//削除する } /// <summary> /// 新規ユーザーがネットワーク経由でマスターに自分の情報を送る /// </summary> public void NewPlayerGet(string name)//イベントを発生させる関数 { //objectは色々な型を入れることができる: object[] info = new object[4];//データ格納配列を作成 info[0] = name;//名前 info[1] = PhotonNetwork.LocalPlayer.ActorNumber;//ユーザー管理番号 info[2] = 0;//キル info[3] = 0;//デス // RaiseEventでカスタムイベントを発生:データを送る PhotonNetwork.RaiseEvent((byte)EventCodes.NewPlayer,//発生させるイベント info,//送るもの(プレイヤーデータ) new RaiseEventOptions { Receivers = ReceiverGroup.MasterClient },//ルームマスターだけに送信される設定 new SendOptions { Reliability = true }//信頼性の設定:信頼できるのでプレイヤーに送信される ); } /// <summary> ///送られてきた新プレイヤーの情報をリストに格納する /// </summary> public void NewPlayerSet(object[] data)//マスターが行う処理 イベント発生時に行う処理 { PlayerInfo player = new PlayerInfo((string)data[0], (int)data[1], (int)data[2], (int)data[3]);//ネットワークからプレイヤー情報を取得 playerList.Add(player);//リストに追加 ListPlayersGet();//マスターが取得したプレイヤー情報を他のプレイヤーに共有 } /// <summary> /// 取得したプレイヤー情報をルーム内の全プレイヤーに送信する /// </summary> public void ListPlayersGet()//マスターが行う処理 イベントを発生させる関数 { object[] info = new object[playerList.Count + 1];//ゲームの状況&プレイヤー情報格納配列作成 info[0] = state;//最初にはゲームの状況を入れる for (int i = 0; i < playerList.Count; i++) //参加ユーザーの数分ループ { object[] temp = new object[4];//一時的格納する配列 temp[0] = playerList[i].name; temp[1] = playerList[i].actor; temp[2] = playerList[i].kills; temp[3] = playerList[i].deaths; info[i + 1] = temp;//プレイヤー情報を格納している配列に格納する。0にはゲームの状態が入っているため+1する。 } //RaiseEventでカスタムイベントを発生:データを送る PhotonNetwork.RaiseEvent((byte)EventCodes.ListPlayers,////発生させるイベント info,//送るもの(プレイヤーデータ) new RaiseEventOptions { Receivers = ReceiverGroup.All },//全員に送信するイベント設定 new SendOptions { Reliability = true }//信頼性の設定:信頼できるのでプレイヤーに送信される ); } /// <summary> /// ListPlayersSendで新しくプレイヤー情報が送られてきたので、リストに格納する /// </summary> public void ListPlayersSet(object[] data)//イベントが発生したら呼ばれる関数 全プレイヤーで呼ばれる { playerList.Clear();//既に持っているプレイヤーのリストを初期化 state = (GameState)data[0];//ゲーム状態を変数に格納 for (int i = 1; i < data.Length; i++)//1にする 0はゲーム状態なので1から始める { object[] info = (object[])data[i];// PlayerInfo player = new PlayerInfo( (string)info[0],//名前 (int)info[1],//管理番号 (int)info[2],//キル (int)info[3]);//デス playerList.Add(player);//リストに追加 } } /// <summary> /// キル数やデス数を取得する関数(プレイヤー識別数、キルかデスを数値で判定、加算する数値) /// </summary> public void ScoreGet(int actor, int stat, int amount) { object[] package = new object[] { actor, stat, amount }; //データを送るイベント PhotonNetwork.RaiseEvent((byte)EventCodes.UpdateStat,//発生させるイベント package,//送るもの(プレイヤーのキルデスデータ) new RaiseEventOptions { Receivers = ReceiverGroup.All },//全員に送信するイベント設定 new SendOptions { Reliability = true }//信頼性の設定:信頼できるのでプレイヤーに送信される ); } /// <summary> /// 受け取ったデータからリストにキルデス情報を追加 /// </summary> public void ScoreSet(object[] data) { int actor = (int)data[0];//識別数 int stat = (int)data[1];//キルなのかデスなのか int amount = (int)data[2];//加算する数値 for (int i = 0; i < playerList.Count; i++)//プレイヤーの数分ループ { if (playerList[i].actor == actor)//情報を取得したプレイヤーと数値が合致したとき { switch (stat) { case 0://キル playerList[i].kills += amount; break; case 1://デス playerList[i].deaths += amount; break; } break;//処理はできたのでこれ以降for文を回さないためにブレイクする } } } /// <summary> /// スコアボードを表示する関数 /// </summary> void ShowScoreboard() { uiManager.ChangeScoreUI();//スコアUIを開く foreach (PlayerInformation info in playerInfoList)//リストの数分ループ { Destroy(info.gameObject);//スコアボードに表示されている一人一人の成績表示UIを削除 } playerInfoList.Clear();//リストから削除 foreach (PlayerInfo player in playerList)//ゲームに参加しているプレイヤーの数分ループ { PlayerInformation newPlayerDisplay = Instantiate(uiManager.info, uiManager.info.transform.parent);//プレイヤー情報を表示するオブジェクトを生成 newPlayerDisplay.SetPlayerDetailes(player.name, player.kills, player.deaths);//生成したオブジェクトに成績を反映 newPlayerDisplay.gameObject.SetActive(true);//表示 playerInfoList.Add(newPlayerDisplay);//リストに追加 } } } [System.Serializable] public class PlayerInfo//プレイヤー情報を管理するクラス { public string name;//名前 public int actor, kills, deaths;//番号、キル、デス //情報を格納 public PlayerInfo(string _name, int _actor, int _kills, int _death) { name = _name; actor = _actor; kills = _kills; deaths = _death; } }
他の講座クーポン【93%OFF】
関連記事
クーポン期限2023/01/24 Udemyでは定価24000円になっていますがこのクーポンページからの購入で1800円台で購入することが可能になっています! 30日以内な[…]
Udemyよりお得に講座視聴可能なYouTubeメンバーシップ