2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Unity】unity-simple-ranking にキャラクターアイコンを表示させる

Last updated at Posted at 2022-10-10

やったこと

unity-simple-ranking を改造して、ランキングデータベースに各プレイヤーのキャラクターアイコンを登録できるようにしました。
更に、それをランキング画面に表示できるようにしました。

(Unity1Week の参加作品 にて、これを実装してみました。)

※ unity-simple-ranking の中身を編集しているので気を付けてください。

image.png

環境

・Unity 2021.3.8f1
・unity-simple-ranking v2.2
・NCMB v4.5.0

準備

https://blog.naichilab.com/entry/webgl-simple-ranking を参考に、NCMB と unity-simple-ranking をプロジェクトにインポートしてください

方針

「ランキング画面呼び出し時」、「データベース登録時」、「ランキング表示時」にそれぞれ処理を加えます。

ランキング画面呼び出し時

unity-simple-ranking では、ランキング画面呼び出し時に、自分のスコアを引数で渡しています。 (RankingLoader.Instance.SendScoreAndShowRanking()で呼んでいます。)
ここに、キャラクターアイコンID も引数で渡すようにします。

データベース登録時

unity-simple-ranking では、RankingSceneManager.cs 内の SendScoreEnumerator() でレコード登録処理をしています。
「名前」と「スコア」の2つのデータを含んだレコードを、データベースに登録しています。

image.png
ランキング表示時、この2つのデータからでは「キャラクターアイコン」の情報を得ることが出来ません。
従って、ランキング登録時に キャラクターアイコンID名前スコア の3つのデータを含んだレコードを、データベースに登録する必要があります。

キャラクターアイコンは、アイコン画像そのものを登録するのではなく、「どのキャラクターアイコンか」を判別するための ID を登録します。ここでは整数値で登録します。
↑ の対応により、ランキング画面呼び出し時の引数に キャラクターアイコンID を追加したので、それを登録します。

image.png

ランキング表示時

↑ の対応により、各レコードには キャラクターアイコンID のデータが含まれているので、表示側では ID に対応する画像を表示します。

ランキング表示時の各ノードは naichilab\unity-simple-ranking\Prefabs\RankingNode.prefab を使用しています。
このプレハブには、キャラクターアイコンを表示する場所が用意されていません。従って、キャラクターアイコン表示用のオブジェクト、コンポーネントを追加しておく必要がります。
image.png
image.png
(それと、当然ですがキャラクターアイコン画像を用意しておきましょう。)

実装

スクリプト

ランキング画面呼び出し

RankingLorder.cs に、フィールドを追加します。

RankingLorder.cs
        [NonSerialized] public int LastIcon = 0; // ランキング呼び出し側で指定したキャラクターアイコンを一時保存する場所

RankingLorder.cs に、「キャラクターアイコンID を引数に入れられるランキング画面呼び出し関数」を追加します。

RankingLorder.cs
        public void SendScoreAndShowRankingWithIcon(TimeSpan time, int icon = 0, int boardId = 0)
        {
            var board = RankingBoards.GetRankingInfo(boardId);
            var sc = new TimeScore(time, board.CustomFormat);
            SendScoreAndShowRankingWithIcon(sc, icon, board);
        }

        public void SendScoreAndShowRankingWithIcon(double score, int icon = 0, int boardId = 0)
        {
            var board = RankingBoards.GetRankingInfo(boardId);
            var sc = new NumberScore(score, board.CustomFormat);
            SendScoreAndShowRankingWithIcon(sc, icon, board);
        }

        private void SendScoreAndShowRankingWithIcon(IScore score, int icon = 0, RankingInfo board)
        {
            if (board.Type != score.Type)
            {
                throw new ArgumentException("スコアの型が違います。");
            }

            CurrentRanking = board;
            LastScore = score;
            LastIcon = icon; // ここで引数のキャラクターアイコンIDを保存。ランキングシーンで参照されます
            SceneManager.LoadScene("Ranking", LoadSceneMode.Additive);
        }
データベース登録

RankingSceneManager.cs に以下の定数、フィールド、シリアライズフィールドを追加します。

RankingSceneManager.cs
    private const string COLUMN_ICON = "icon"; // レコード内の項目名
    private int _lastIcon; // 自分のキャラクターアイコンID。自分のランキングを送信するときに使用
    [SerializeField] private Sprite[] icons; // キャラクターアイコン画像の配列。ここに入っている画像を表示します

RankingSceneManager.csStart() にて、 RankingLoader.csLastIcon フィールド値を読み込みます。

RankingSceneManager.cs
        void Start()
        {
            sendScoreButton.interactable = false;
            _board = RankingLoader.Instance.CurrentRanking;
            _lastScore = RankingLoader.Instance.LastScore;
            _lastIcon = RankingLoader.Instance.LastIcon; // ← ここ追加
            Debug.Log(BoardIdPlayerPrefsKey + "=" + PlayerPrefs.GetString(BoardIdPlayerPrefsKey, null));

            StartCoroutine(GetHighScoreAndRankingBoard());
        }

RankingSceneManager.csSendScoreEnumerator() にて、送信用データに キャラクターアイコンID を追加で登録します。

RankingSceneManager.cs
        private IEnumerator SendScoreEnumerator()
        {
            sendScoreButton.interactable = false;
            highScoreLabel.text = "送信中...";

            //ハイスコア送信
            if (_ncmbRecord == null)
            {
                _ncmbRecord = new NCMBObject(_board.ClassName);
                _ncmbRecord.ObjectId = ObjectID;
            }

            _ncmbRecord[COLUMN_NAME] = InputtedNameForSave;
            _ncmbRecord[COLUMN_SCORE] = _lastScore.Value;
            _ncmbRecord[COLUMN_ICON] = _lastIcon; // ← ここ追加

            ...以下略...

        }
ランキング表示

RankingNode.cs にキャラクターアイコン表示用のフィールドIconを追加します

RankingNode.cs
	public class RankingNode : MonoBehaviour
	{
		public Text NoText;
		public Text NameText;
		public Text ScoreText;
		public Image Icon; // ← ここ追加
	}

RankingSceneManager.csLoadRankingBoard()にて、生成したインスタンスに キャラクターアイコンIDを入れます。

RankingSceneManager.cs
        private IEnumerator LoadRankingBoard()
        {

           ...以前略...

                foreach (var r in so.Result)
                {
                    var n = Instantiate(rankingNodePrefab, scrollViewContent);
                    var rankNode = n.GetComponent<RankingNode>();
                    rankNode.NoText.text = (++rank).ToString();
                    rankNode.NameText.text = r[COLUMN_NAME].ToString();

                    var iconID = int.Parse(r[COLUMN_ICON].ToString()); // ← ここ追加
                    rankNode.Icon.sprite = icons[iconID]; // ← ここ追加
                    
                    var s = _board.BuildScore(r[COLUMN_SCORE].ToString());
                    rankNode.ScoreText.text = s != null ? s.TextForDisplay : "エラー";

//                    Debug.Log(r[COLUMN_SCORE].ToString());
                }

            ...以下略...

        }

プレハブ、シーン

RankingNode.prefabに空のオブジェクトを追加します。
image.png
・↑ のオブジェクトに Image コンポーネントをアタッチします。
image.png

・さらに、RankingNodeコンポーネントの Icon 項目に、先ほどのImageをアタッチします。
image.png

Ranking.unityシーンを開き、RankingSceneManagerコンポーネントの Icons 項目に、キャラクターアイコン画像を入れておきます。 (キャラクターアイコンIDと画像の順番を合わせておいてください。)
image.png

ランキングを開く

こんな感じで開きます。

    {
        double score = 100d; // ← スコア。ゲーム内のスクリプトから適宜拾ってくる
        int icon = 1; // ← 現在使用しているキャラクターのID。ゲーム内のスクリプトから適宜拾ってくる
        int board = 0; // ← ランキング番号。ランキングの種類が1つだけなら0

        RankingLoader.Instance.SendScoreAndShowRankingWithIcon(score, icon, board);
    }

実行するとこんな感じで出ます。
image.png

その他、応用

キャラクターアイコン画像のサイズは、 RankingNode.prefab の Height よりも小さくする必要があります (はみ出さないようにするために)
image.png

おそらく、デフォルトの Height のままキャラクターアイコンを表示しようとすると、小さい印象を持つと思います。アイコンを大きく表示するためには、RankingNode.prefab の Height 値を大きくすると良いでしょう。

参考

【Unity、WebGL】なるべく簡単にオンラインランキング機能をつけるサンプル
Unity1Week 参加作品「Accumulate Jump Run」

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?