[Unity] アイテム一覧ページっぽいものを作ってみる

Nプログラマです。

今回の内容は、以下のように道具袋のイメージしたアイテム一覧とページ送り機能をつけたものを作ってみます。

概要

目標

  • アイテム一覧とページ送り機能を作ってみる

環境情報

  • Unity: 2018 3.6f1
  • テンプレート: 2D

今回使う画像

今回使うアイテムの画像です。

ソースコード

Menu.cs コードを開く
Menu.cs
using UnityEngine;

public class Menu : MonoBehaviour
{
    // アイテムのデータ
    // 0番目: アイテムの名前
    // 1番目: アイテムの説明
    // 2番目: アイテムの画像名
    private string[][] itemData =
    {
        // 1ページ目
        new string[] {"赤いポーション(小)", "HPを少しだけ回復する。意外と少ない。味は甘い。", "Potion_Red" },
        new string[] {"赤いポーション(中)", "HPを中くらい回復する。まぁまぁの量。ゴクゴク飲める。", "Potion_Red" },
        new string[] {"赤いポーション(大)", "HPを大きく回復する。量的に連続で飲むのはツラい。", "Potion_Red" },
        // 2ページ目
        new string[] {"青いポーション(小)", "SPを少しだけ回復する。味がにがい。量が少ないので助かる。", "Potion_Blue" },
        new string[] {"青いポーション(中)", "SPを中くらい回復する。量が増えて味もにがいのでキツい。", "Potion_Blue" },
        new string[] {"青いポーション(大)", "SPを大きく回復する。なぜかこれだけものすっごくにがい。", "Potion_Blue" },
        // 3ページ目
        new string[] {"紫色のポーション(小)", "HPとSPを少しだけ回復する。赤と青ポーションを混ぜたもの。ものすごい複雑な味。", "Potion_Purple" },
        new string[] {"紫色のポーション(中)", "HPとSPを中くらい回復する。量も増えて味も増えた。具体的には、甘い、苦い、辛い、酸っぱい、塩辛いの五味。", "Potion_Purple" },
        new string[] {"紫色のポーション(大)", "HPとSPを大きく回復する。五味の極地なる味。これが飲みたくなくて冒険をやめる冒険者もいるほど。", "Potion_Purple" },
    };

    private int currentPage = 0;  // 現在のページ
    private int maxPage = 2;      // 3ページまで
    private int perPage = 3;      // 1ページに表示するアイテムの数
    
    public Item[] items = new Item[3];    // インスペクタでsizeを3に設定する
    
    void Start()
    {
        Init();
    }

    private void Init()
    {
        for (int i = 0; i < items.Length; i++)
        {
            var itemDataIndex = i + (currentPage * perPage);
            items[i].Init(itemData[itemDataIndex]);
        }
    }

    public void OnNextClick()
    {
        currentPage++;
        if (currentPage > maxPage)
        {
            currentPage = 0;
        }

        Init();
    }

    public void OnPrevClick()
    {
        currentPage--;
        if (currentPage < 0)
        {
            currentPage = maxPage;
        }

        Init();
    }
}

説明

アイテムデータの表示

itemData変数に表示するためのアイテムデータが入っています。 データ構造はこんな感じ。

  • 0番目: アイテム名
  • 1番目: アイテムの説明文
  • 2番目: アイテムの画像名

このデータを使って初期化するのがInitメソッドです。 一番最初はStartで呼び出されて、その後は「Next」 or「 Prev」のボタンを押すたびに呼び出されて表示するデータを切り替えています。

ページ

アイテムデータの配列のインデックスを管理しています。

Initメソッドでページに対応する配列のインデックスを計算して、表示するアイテムデータを決めています。

var itemDataIndex = i + (currentPage * perPage);
表示されるページと配列の対応表
ページ アイテム1列目 アイテム2列目 アイテム3列目
1ページ 配列[0] 配列[1] 配列[2]
2ページ 配列[3] 配列[4] 配列[5]
3ページ 配列[6] 配列[7] 配列[8]

次のページめくりは一番最後まで来たら、一番最初に戻るようにしています。
前のページめくりも次へと同じで一番最初まで来たら、一番最後にもどります。

Item.cs コードを開く
Item.cs
using UnityEngine;
using UnityEngine.UI;

public class Item : MonoBehaviour
{
    public Image itemImage;
    public Text itemName;
    public Text itemDesc;

    // 配列要素の0番目: アイテムの名前
    // 配列要素の1番目: アイテムの説明
    public void Init(string[] itemData)
    {
        itemName.text = itemData[0];
        itemDesc.text = itemData[1];
        itemImage.sprite = Resources.Load<Sprite>("Textures/" + itemData[2]);
    }
}

説明

アイテムデータの表示を担当するクラスです。以下のコンポーネントの参照を持っており、Initメソッドで内容が初期化されます。

  • itemName: アイテム名前
  • itemDesc: アイテムの説明
  • itemImage: アイテムの画像

アイテムを表示するコンポーネントは常に3つ固定で、データ毎に表示する内容を切り替えています。
事前にインスペクタでそれぞれのコンポーネントの参照を設定しておきましょう。

準備

画像

Assetsの直下にTexturesディレクトリを作成して、その中にポーションの画像を入れましょう。

  • 赤いポーション: Textures/Potion_Red.png
  • 青いポーション: Textures/Potion_Blue.png
  • 紫色のポーション: Textures/Potion_Purple.png

シーン

スクリプトのアタッチや、参照を設定しておきます。

ヒエラルキー

Menu.csとItem.csを以下のゲームオブジェクトにアタッチします。

  • MenuゲームオブジェクトにMenu.csをアタッチ
  • Item0, Item1, Item2ゲームオブジェクトにItem.csをアタッチ

Item.cs インスペクタ

Item0, Item1, Item2のそれぞれの子コンポーネントのImage, Name, Descの参照を設定します。

/img/article/2019/03/15/04.png
Itemゲームオブジェクトのインスペクタ

先ほどのItem0, Item1, Item2のItemコンポーネントの参照を設定します。 sizeが0になっているので、3に設定して0番目にItem0、1番目にItem1、2番目にItem2の参照を設定します。

/img/article/2019/03/15/05.png
Menuゲームオブジェクトのインスペクタ

これで準備は完了です。実行してみましょう。

実行結果

1ページ目

赤いポーション一覧、味は甘い。

/img/article/2019/03/15/06.png
赤いポーション一覧

2ページ目

青いポーション一覧、味は苦い。

/img/article/2019/03/15/07.png
青いポーション一覧

3ページ目

紫色のポーション一覧、味はもうよく分からない。。。

/img/article/2019/03/15/08.png
紫色ポーション一覧

課題

現在のページ処理をクラスへ切り出せそうだ。。。!

今回はアイテムページ一覧の想定ですが、作るゲームによっては様々な一覧ページを表示することもあります。
ショップのアイテム一覧、クエスト一覧、合成一覧などなど。。。

そのたびにページのインデックス管理の部分をコピペすると、同じコードが増えてきてメンテが大変になってきそうです。
(もちろん、これでもう変更する予定がない場合はそのままでオッケーです)

なのでこの部分はクラスに切り出してみようと思います。

ボタンの共通化

今は「Next」と「Prev」ボタンだけですが、他にも増えてくる可能性がありそうです。

アイテム画像をクリックして使うとか、アイテムの詳細を表示するボタンとかを作ると、OnXXXClickというメソッドが増えてきそうなので、OnClickに共通化したいところ。

これは以前の記事で対応できるので、OnClickメソッドに統一します。

おわりに

今回の内容は、道具袋のイメージしたアイテム一覧とページ送り機能をつけたものを作ってみました。

小さな機能ですが、ちょっとずつ作り慣れてくると楽しいですね。

想像力を膨らませて、楽しいモノを作りましょう。

それでは、このへんで。
バイナリー!



関連した記事