[Unity]ランキングの表示
このチュートリアルは次の内容に続きなります
実行イメージ
起動直後にランキングリストに登録されている情報をUIに表示しています
スペースキーを押下すると更新されたランキングが表示されます
シーンの構成
マネージャオブジェクト
ランキングを更新するためのマネージャオブジェクトです
仮にランカー(ユーザー)ごとのイラストを入れています

ランキングボード
ランキングを表示するCanvasです

ランキングを表示するためにエリア
ランカーを表示するためのエリアを設定しています
Panalになります
エリアの大きさの変更

レイアウトグループの調整

ランキングボタン
個別のランキング情報を表示しています
将来、クリックすると詳細表示もできるようにButtonにしています
ランカーの枠の大きさを指定します

ランカーの情報表示欄を登録します

ランカーイメージアイコン(イラスト)
ランカーのイメージアイコンを表示するエリアです
Imageを貼り付けています

ランカーの名前
ランカーの名前表示エリアです
Textになっています

ランカーのスコア
ランカーのスコア表示エリアです
Textになっています

コード
Ranking
ランキング一覧を管理するスクリプトです
シングルトンで構成され複数のインスタンスの作成はされません
内部クラスに個別のランカー情報を持っています
外部からはリストを取得することができます
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public class Ranking
{
Ranking()
{
}
static Ranking instance;
public static Ranking GetInstance
{
get
{
if (instance == null)
{
instance = new Ranking();
}
return instance;
}
}
public class Ranker
{
public string name;
public Sprite sprite;
public int score;
public Ranker(string name, Sprite sprite, int score)
{
this.name = name;
this.sprite = sprite;
this.score = score;
}
}
List<Ranker> rankers = new List<Ranker>();
public List<Ranker> Rankers => rankers.OrderByDescending(ranker => ranker.score).ToList();
public void Add(string name, Sprite sprite, int score)
{
Ranker ranker = new Ranker(name, sprite, score);
rankers.Add(ranker);
}
public void Remove(string name)
{
rankers.Remove(rankers.Find(score => score.name == name));
}
public void Clear()
{
rankers.Clear();
}
}
RankingDialog
ランキング表示用のエリアにランカーボタンを作成する役割があります
各ランカーは、インスタンスの作成で構成されています
単に追加していますが、LayoutGroupのコンポーネントにより自動的に均等表示されます
using System.Collections.Generic;
using UnityEngine;
public class RankingDialog : MonoBehaviour
{
[SerializeField]
int buttonNumber = 10;
[SerializeField]
RankingButton rankingButton;
RankingButton[] rankingButtons;
private void Awake()
{
CreateButton();
}
private void CreateButton()
{
for (int i = 0; i < buttonNumber - 1; i++)
{
Instantiate(rankingButton, transform);
}
rankingButtons = GetComponentsInChildren<RankingButton>();
}
public void ShowRanking()
{
List<Ranking.Ranker> rankers = Ranking.GetInstance.Rankers;
for (int i = 0; i < rankers.Count; i++)
{
rankingButtons[i].Ranker = rankers[i];
}
}
}
説明
ランカーごとのボタンの生成します
登録されたボタンの数(buttonNumber)分まで繰り返されます
private void CreateButton()
{
for (int i = 0; i < buttonNumber - 1; i++)
{
Instantiate(rankingButton, transform);
}
}
子オブジェクトにアタッチされているRankingButtonスクリプトを配列で取得します
この先使いたいのはこのスクリプトのメンバーなのでオブジェクト自体を取得しなくても良いです
rankingButtons = GetComponentsInChildren<RankingButton>();
ランキングを表示します(実際はランカーのボタンを表示します)
ランカー一覧は、RankingクラスのRankersプロパティに保存されています
このクラスから作られるインスタンスは1つで十分なのでシングルトンの呼び出しを使って取得しています
その後、所得した一覧情報を順番に子オブジェクトから取得したスクリプトのRankerプロパティに代入(セット)して行っています
public void ShowRanking()
{
List<Ranking.Ranker> rankers = Ranking.GetInstance.Rankers;
for (int i = 0; i < rankers.Count; i++)
{
rankingButtons[i].Ranker = rankers[i];
}
}
RankingButton
ランカー個人の情報を表示するボタンを管理しています
オブジェクトがボタンなので、将来クリックすることで何かを実行できるようにすることもできます
ボタンに表示される情報は、ランカー個人アイコン・名前・得点になります
それぞれに設定するように
using UnityEngine;
using UnityEngine.UI;
public class RankingButton : MonoBehaviour
{
[SerializeField]
Image icon;
[SerializeField]
Text nameText;
[SerializeField]
Text scoreText;
Ranking.Ranker ranker;
public Ranking.Ranker Ranker
{
get
{
return ranker;
}
set
{
ranker = value;
icon.sprite = ranker.sprite;
nameText.text = ranker.name;
scoreText.text = ranker.score.ToString();
}
}
}
説明
Ranking.Ranker ranker;
Rankerクラスの情報は、Rankingクラスのインナークラス(クラス内部に記述されたクラス)なので、.(ピリオド、点)で繋いで表現します
内部クラスでない場合だと単に次のようになりますね
Ranker ranker;
UIの各情報(画像イメージ・名前・スコア)に表示する処理を担っています
Rankerプロパティに代入(セット)すること(setが呼ばれる)で、表示されるようになります
Rankerプロパティは、Ranking.Ranker型なので、valueには3つの情報が渡されます
public Ranking.Ranker Ranker
{
set
{
ranker = value;
icon.sprite = ranker.sprite;
nameText.text = ranker.name;
scoreText.text = ranker.score.ToString();
}
}
このプロパティに代入するのは、RankingDialogクラスのShowRankingメソッドになります
for文で繰り返し、順番に代入されます
rankingButtons[i].Ranker = rankers[i];
マネージャ
マネージャーは、ゲームを進行をコントロールする役割があるとします
ゲームオーバーになった際、プレイヤーの得点をもとにランキング管理のためのデータを作成します
プレイヤーの情報としては、クラスで、名前・アイコン・得点をメンバーとして管理しています
using UnityEngine;
public class Sample : MonoBehaviour
{
[SerializeField]
Sprite[] sprites;
[SerializeField]
RankingDialog rankingDialog;
void Start()
{
Ranking ranking = Ranking.GetInstance;
ranking.Add("太郎", sprites[0], 70);
ranking.Add("次郎", sprites[1], 60);
ranking.Add("三郎", sprites[2], 50);
ranking.Remove("次郎");
ranking.Add("四郎", sprites[4], 65);
foreach (var ranker in ranking.Rankers)
{
Debug.Log($"名前:{ranker.name} ポイント:{ranker.score}");
}
rankingDialog.ShowRanking();
}
void Update()
{
if (Input.GetKeyDown(KeyCode.Space))
{
UpdateRanking();
rankingDialog.ShowRanking();
}
}
private void UpdateRanking()
{
Ranking ranking = Ranking.GetInstance;
ranking.Clear();
ranking.Add("五郎", sprites[0], 75);
ranking.Add("六郎", sprites[1], 88);
ranking.Add("七郎", sprites[2], 20);
ranking.Remove("七郎");
ranking.Add("八郎", sprites[3], 10);
foreach (var ranker in ranking.Rankers)
{
Debug.Log($"名前:{ranker.name} ポイント:{ranker.score}");
}
}
}
ディスカッション
コメント一覧
まだ、コメントがありません