学習記事一覧 · Unity

【学習】Unity:アイテム所持とセーブ入門(第2回)― 1 アイテムをクラスに:List で整理

第1回 では、Dictionary名前と個数 をまとめました。

しかし将来、次のような要求が出ます。

  • アイテムの説明文を持たせたい
  • アイコンレア度 を持たせたい

**1 つのアイテムを 1 つの型(クラス)**で表現すると、変更不要な部分を増やしやすくなります。

今回は OwnedItem クラスList<OwnedItem> で、第1回と同じ「増える・減る」を書き換えます。

シリーズ


今日のゴール

  • アイテム 1 種類OwnedItem クラスで表す(名前・個数)
  • List で複数種類を並べ、同じ名前は 1 行にまとめる
  • [Serializable] を付けると、Inspector で中身を見る実験ができる(Unity 上での確認用)

なぜ分ける?

観点 Dictionary クラス + List
拡張 値が int 固定になりがち フィールドを足しやすい
「同一アイテム」の表現 キーが名前 List の 1 要素

完成コード

using System;
using System.Collections.Generic;
using UnityEngine;
public class ItemManager : MonoBehaviour
{
    [SerializeField]
    private List<OwnedItem> ownedItems = new List<OwnedItem>();
    public void AddItem(string itemName, int count)
    {
        OwnedItem item = GetItem(itemName);
        if (item == null)
        {
            item = new OwnedItem(itemName);
            ownedItems.Add(item);
        }
        item.Add(count);
    }
    public void UseItem(string itemName, int count)
    {
        OwnedItem item = GetItem(itemName);
        if (item == null || item.Number < count)
        {
            Debug.Log("アイテムが足りません");
            return;
        }
        item.Use(count);
    }
    private OwnedItem GetItem(string itemName)
    {
        foreach (OwnedItem item in ownedItems)
        {
            if (item.Name == itemName)
            {
                return item;
            }
        }
        return null;
    }
}
[Serializable]
public class OwnedItem
{
    [SerializeField] private string name;
    [SerializeField] private int number;
    public string Name => name;
    public int Number => number;
    public OwnedItem(string itemName)
    {
        name = itemName;
    }
    public void Add(int count)
    {
        number += count;
    }
    public void Use(int count)
    {
        number -= count;
    }
}

手を動かす

  1. 第1回の SimpleItemManager入れ替えるか、別オブジェクトで試す
  2. Play 中に InspectorOwned Items を展開し、個数が変わることを見る
  3. StartAddItem / UseItem を呼び、Debug.Log と Inspector の両方で確認する

プログラムの流れ

AddItem

GetItem で既存を探す(なければ new して List に追加)

OwnedItem.Add で個数加算
UseItem

無ければ/不足ならログ

OwnedItem.Use で減算

重要ポイント

  • OwnedItem … 「そのアイテムの状態」を閉じた小さなモデル
  • GetItemList線形探索(数が増えたら辞書にする等の最適化は後回しでよい)
  • [Serializable] … Unity の JsonUtility が扱いやすい形の第一歩(次回につながる)

発展アイデア

  • string の代わりに enum ItemType(木・石など)に変える(書籍サンプルに近づく)
  • Debug.LogownedItems 全件を一覧表示する

次に進む

Play を止めると まだ消えます。次は 端末に残す ために PlayerPrefs と JSON を使います。

第3回:PlayerPrefs と JSON で保存する