Unityで作るランキング表示のベストプラクティス
ゲームやアプリにランキングを導入すると、ユーザー同士の競争心を刺激し、継続利用を促す効果があります。本記事では、Unityでランキングを表示する方法を、UI構築・データ構造・更新処理の3つの観点から解説します。単純なサンプルから始め、実際に使いやすいコードへ改良していく流れを追っていきましょう。
UIの準備
ランキングは「縦に並んだリストUI」が基本です。以下の構成でCanvasに配置します。
- RankingDialog (Panel)
- ScrollView
- Viewport
- Content(縦方向に並べる)
- Viewport
- ScrollView
- RankingButton(Prefab)
- 名前テキスト
- スコアテキスト
- アイコン画像
配置には Vertical Layout Group を利用し、自動整列を行います。
テキストには TextMeshPro を推奨します。可読性と装飾性が高く、今後のUnity開発では必須に近い存在です。
データ構造(ランキングクラス)
シングルトンを使ってランキングデータを集中管理します。
using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
public sealed class Ranking
{
private Ranking() {}
private static Ranking _instance;
public static Ranking Instance => _instance ??= new Ranking();
// ランキングの1件を表すデータ構造
public sealed class Ranker
{
public string Name { get; }
public Sprite Icon { get; }
public int Score { get; }
public Ranker(string name, Sprite icon, int score)
=> (Name, Icon, Score) = (name, icon, score);
}
private readonly List<Ranker> _rankers = new();
public IReadOnlyList<Ranker> Rankers
=> _rankers.OrderByDescending(r => r.Score).ToList();
public void Add(string name, Sprite icon, int score)
=> _rankers.Add(new Ranker(name, icon, score));
public bool Remove(string name)
=> _rankers.Remove(_rankers.Find(r => r.Name == name));
public void Clear() => _rankers.Clear();
}
UI更新処理
ランキングを表示するUIコントローラです。
using System.Collections.Generic;
using UnityEngine;
using TMPro;
using UnityEngine.UI;
public class RankingDialog : MonoBehaviour
{
[SerializeField] Transform content;
[SerializeField] GameObject rankingButtonPrefab;
private readonly List<GameObject> _buttons = new();
public void ShowRanking()
{
var rankers = Ranking.Instance.Rankers;
// 差分更新:必要数だけ再利用または生成
for (int i = 0; i < rankers.Count; i++)
{
GameObject button;
if (i < _buttons.Count)
{
button = _buttons[i];
button.SetActive(true);
}
else
{
button = Instantiate(rankingButtonPrefab, content);
_buttons.Add(button);
}
var rb = button.GetComponent<RankingButton>();
rb.Set(rankers[i].Name, rankers[i].Icon, rankers[i].Score);
}
// 余分なボタンは非表示
for (int i = rankers.Count; i < _buttons.Count; i++)
_buttons[i].SetActive(false);
}
}
各ボタンの制御
ランキング1件分の表示用Prefab側スクリプトです。
using TMPro;
using UnityEngine;
using UnityEngine.UI;
public class RankingButton : MonoBehaviour
{
[SerializeField] TMP_Text nameText;
[SerializeField] TMP_Text scoreText;
[SerializeField] Image iconImage;
public void Set(string name, Sprite icon, int score)
{
nameText.text = name;
scoreText.text = score.ToString();
iconImage.sprite = icon;
}
}
発展:データ永続化
ランキングを一時的に表示するだけでなく、データ保存・共有にも対応可能です。
- ローカル保存JsonUtility を利用して Ranker リストをシリアライズ → PlayerPrefsやファイルに保存。
- ネット同期サーバーAPIと連携すれば、全プレイヤー共通のランキング表示も実現できます。
よくあるハマりポイント
- TextとTextMeshProの混在開発初期からTMPに統一しておくと混乱を避けられる。
- Layout Groupのスペルミス“Panel”や“Layout”の綴り間違いでInspector参照が外れることがある。
- ソートのタイミング「追加時にソート」か「表示時にまとめてソート」か方針を決めておくことが大切。
まとめ
- ランキング実装の基本は「データの並べ替え」と「UIへの反映」。
- 本記事では 命名改善・差分更新・TMP統一 を取り入れた完成例を紹介しました。
- 小規模ならシンプルに、大規模なら責務分離やオブジェクトプールなどを導入しましょう。
ランキングはゲームにおけるモチベーションの源泉です。まずは本記事のサンプルを試し、自身のゲームに合わせてカスタマイズしてみてください。
ni
訪問数 6 回, 今日の訪問数 6回
ディスカッション
コメント一覧
まだ、コメントがありません