😺

アクション・RPG・脱出ゲームで使えるアイテム管理の実装方法

2025/01/11に公開

アクション・RPG・脱出ゲームで使えるアイテム管理の実装方法

ゲーム内でアイテムを取得・所持・使用できる仕組みは、多くのジャンル(アクション、RPG、脱出ゲームなど)に必須の要素です。しかし、どうやって実装すればスムーズかつ拡張しやすいアイテムシステムを構築できるのか、悩んだことはありませんか?この記事では、アイテム管理の考え方サンプルコードInspectorでの設定、そしてUIの表示をわかりやすく解説します。ぜひ参考にして、アイテムを使ったゲーム体験を豊かにしてみてください。

アイテム管理の必要性と問題点

よくある課題:どのようにアイテムを管理すればいいの?

ゲームにおいて、プレイヤーが複数のアイテムを持ったり、それらを使ってイベントを解決する場面はとても多いです。具体的には次のような問題が起こりがちです。

  • 同じアイテムを何度も使えるようにしたいのか、それとも使ったら無くなるのか
  • アイテムごとに名前や説明、アイコン画像などをどうひとまとめにするか
  • 所持アイテムをUIに反映するときの手間が大きい
  • スクリプト同士の連携が複雑になり、バグが起きやすい

一つひとつ手作りで対応するのも可能ですが、大規模になれば管理が煩雑になります。そこでリストやクラスを使って、アイテム情報を整理したり、Inspectorからアイコンや名前を設定できるようにしておくのが定番のアプローチです。

解決策の方向性:オブジェクト指向+ScriptableObject or Class

アイテムをクラスScriptableObjectとして定義し、まとめて管理する方法がよく使われます。

  • オブジェクト指向的に、アイテムの属性(名前、アイコン、効果など)をまとめる
  • アイテムをリスト化し、プレイヤーが所持しているものだけを保持
  • UIへの反映は、リストの中身を走査してボタン・アイコンを生成

この仕組みをベースにしておけば、アイテムを追加・変更するときも影響範囲が限定的になり、開発効率がぐっと高まります。

必要なプログラムの考え方

アイテムの情報クラスを定義する

アイテムを表すクラスを用意し、アイテム名や説明文、アイコン画像、スタック可能数などのフィールドを持たせます。これにより、1つのクラスがアイテムの情報を包括的に保有できるようになります。

例:Itemクラスの設計

  • itemID : アイテムを一意に特定するID
  • itemName : アイテムの名前
  • itemDescription : アイテムの説明文
  • itemIcon : アイテムのアイコン画像(Spriteなど)
  • maxStack : スタック(まとめて持てる数)可能数

アイテムを管理するItemManagerクラス

プレイヤーが持っているアイテムを一括管理するために、ItemManagerというスクリプトを作成します。ItemManagerは、下記のような責務を持ちます。

  • ゲーム開始時にアイテムリストを初期化
  • アイテムを追加・削除する関数を提供
  • アイテムの個数が変化したらUIを更新
  • 必要に応じてアイテムを使うタイミングを通知

脱出ゲームの場合は、鍵やヒントアイテムを取得してイベントを進行したり、RPGなら薬草や装備品を管理したりと、それぞれのジャンルで応用できます。

プログラムのサンプル

1. アイテムを表すクラス

using UnityEngine;

[System.Serializable]
public class Item
{
    public int itemID;
    public string itemName;
    public string itemDescription;
    public Sprite itemIcon;
    public int maxStack = 1;
}

2. ItemManagerスクリプト

using UnityEngine;
using System.Collections.Generic;

public class ItemManager : MonoBehaviour
{
    // プレイヤーが所持しているアイテム一覧
    public List<Item> items = new List<Item>();

    // アイテムを追加
    public void AddItem(Item newItem)
    {
        // 既に同じIDのアイテムがある場合 → スタックできるか確認
        // 同じIDが無い場合は新規追加
        Item existing = items.Find(i => i.itemID == newItem.itemID);
        if (existing != null && existing.maxStack > 1)
        {
            // スタック数量の制御は必要に応じて拡張
            // 例: existing.count += 1;
            Debug.Log("Stack the item!");
        }
        else
        {
            items.Add(newItem);
            Debug.Log("Add new item: " + newItem.itemName);
        }

        // UIを更新
        UpdateInventoryUI();
    }

    // アイテムを削除
    public void RemoveItem(int itemID)
    {
        Item target = items.Find(i => i.itemID == itemID);
        if (target != null)
        {
            items.Remove(target);
            Debug.Log("Removed item: " + target.itemName);
        }

        // UIを更新
        UpdateInventoryUI();
    }

    private void UpdateInventoryUI()
    {
        // 所持アイテムに応じてUIを更新する
        // 具体的なUI更新方法は別途解説
    }
}

上記の例では最小限の処理しか書いていませんが、AddItemで同一アイテムをスタックする処理を追加すれば、ポーションを複数まとめて持てるようになります。RemoveItemでは、アイテムを消費したり破棄する場合のロジックが書けます。

3. アイテムを拾う処理(Player側のサンプル)

using UnityEngine;

public class PlayerItemPickup : MonoBehaviour
{
    public ItemManager itemManager;

    private void OnTriggerEnter(Collider other)
    {
        // "Pickup"タグの付いたオブジェクトに触れたらアイテム取得
        if (other.CompareTag("Pickup"))
        {
            ItemObject itemObject = other.GetComponent<ItemObject>();
            if (itemObject != null)
            {
                itemManager.AddItem(itemObject.itemData);
                Destroy(other.gameObject);
            }
        }
    }
}

OnTriggerEnterを利用して、"Pickup"とタグ付けされたオブジェクトに触れたらアイテムを取得。ItemObjectというスクリプトで管理している"itemData"をAddItemで登録した後、オブジェクトを削除します。

プログラムの解説

ItemObjectスクリプト(アイテムをフィールドに配置するために)

アイテムを「シーン上のオブジェクト」として配置したい場合、以下のようなスクリプトを用意して、どのアイテム情報を持っているかを管理します。

using UnityEngine;

public class ItemObject : MonoBehaviour
{
    public Item itemData;
}

この"itemData"をInspectorで指定しておけば、拾ったときにどのアイテムをAddItemするかが一目瞭然になります。

Inspectorでの設定方法

  1. Assetsフォルダ内で C# Script → "Item.cs" と "ItemManager.cs"、"ItemObject.cs" を用意
  2. Prefabフォルダを作成 → "PickupItem.prefab" などに "ItemObject" をアタッチ
  3. ItemObjectコンポーネントの itemData フィールドに、さきほど作った "Item" クラスのインスタンスを割り当て(ScriptableObjectにしてもOK)
  4. "ItemManager.cs" をシーン上のGameObject(例:GameManager)にアタッチ
  5. "PlayerItemPickup.cs" をプレイヤーのGameObjectにアタッチし、Inspectorで "itemManager" を指定

これで、プレイヤーが "PickupItem.prefab" のオブジェクトに触れると、対応するアイテム情報がItemManagerに登録される流れが完成します。

UIの設定

インベントリUIの表示例

1. インベントリの枠(GridLayoutなど)の準備

  • Unityの"Canvas"上に"Panel"を作成
  • "Grid Layout Group"を付けてアイコンを並べるとわかりやすい

2. アイテムスロットをPrefab化

アイテムを1つ表示するスロットをPrefabとして作成し、以下を含めます:

  • Image : アイコン用
  • Text : アイテム名や個数表示用
public class InventoryUI : MonoBehaviour
{
    public GameObject slotPrefab; // スロットのPrefab
    public Transform slotParent;  // GridLayoutを持つ親のTransform

    public void RefreshUI(List<Item> items)
    {
        // 一旦全削除
        foreach(Transform child in slotParent)
        {
            Destroy(child.gameObject);
        }

        // 再生成
        foreach(Item item in items)
        {
            GameObject slot = Instantiate(slotPrefab, slotParent);
            SlotController slotCtrl = slot.GetComponent<SlotController>();
            slotCtrl.SetupSlot(item);
        }
    }
}

RefreshUIメソッドでは、現在所持しているアイテム数に応じてスロットを再生成します。シンプルな例では、すべてを作り直す形でも問題ありません。大量のアイテムを扱うなら、プールや差分更新を考慮します。

3. SlotControllerスクリプト

using UnityEngine;
using UnityEngine.UI;

public class SlotController : MonoBehaviour
{
    public Image icon;
    public Text itemNameText;

    public void SetupSlot(Item item)
    {
        icon.sprite = item.itemIcon;
        itemNameText.text = item.itemName;
    }
}

SetupSlotでアイテム情報をUIに反映します。スロットPrefab内のImageやTextを事前にInspectorで紐付けておけば、このスクリプトを呼び出すだけでアイコンや名前を差し替えられます。

ItemManagerからUIを更新する

先のUpdateInventoryUI()メソッドで、InventoryUIRefreshUI()を呼び出します。

public InventoryUI inventoryUI;

private void UpdateInventoryUI()
{
    if(inventoryUI != null)
    {
        inventoryUI.RefreshUI(items);
    }
}

これでアイテムを追加・削除するたびに、UIがリフレッシュされるようになります。

発展的な応用

1. 複数種類のアイテムを区別する

  • 回復アイテム、鍵アイテム、装備品などを区別し、使用処理や装備処理を分ける
  • ScriptableObjectにアイテムタイプを持たせ、switch文などで分岐する

2. アイテムの使用効果をスクリプト化

アイテムを使ったときに発動する"Use()"メソッドをItemクラスや派生クラスで実装するアプローチもあります。

public virtual void Use()
{
    Debug.Log("Use " + itemName);
}

継承を使えば、「鍵アイテム」ではドアを開ける、「回復アイテム」ではHPを回復する…といったカスタム処理を分散して記述できます。

3. セーブ&ロード対応

アイテム情報を永続化したい場合は、所持しているアイテムのIDと個数をJSONやScriptableObjectで保存し、ゲーム起動時に読み込むようにします。

[System.Serializable]
public class SaveData
{
    public List<int> itemIDs;
    // もしスタック数がある場合は、itemIDsと同じインデックスでcountを持つ
}

public class GameSaveManager : MonoBehaviour
{
    public ItemManager itemManager;

    public void SaveItems()
    {
        // itemManager.items から itemIDs に変換して JSON化 → ファイルに書き出す
    }

    public void LoadItems()
    {
        // JSONファイルから itemIDs を読み込み、ItemManagerに追加
    }
}

ゲームの種類や設計に応じて、簡易実装でも完全にデータを保持するでも自由に拡張可能です。

まとめ:アイテム管理システムでゲームに奥行きを

  • "Item" クラスやScriptableObjectでアイテム情報を一元管理
  • "ItemManager" が追加・削除・更新・UI反映などの機能を集約
  • UIはスロットPrefab+"RefreshUI"で柔軟に表示
  • アクション・RPG・脱出ゲーム問わず、同じ仕組みで大体対応可能

アイテム管理の実装は、複数のコンポーネントやクラスが連動するため、最初は少し手間取るかもしれません。しかし、一度基本形を作ってしまえば、アイテム数を増やしても管理が楽になるメリットがあります。ぜひこの記事を参考に、自分のゲームにぴったりのアイテムシステムを構築してみてください!

この記事を読んでもっと実践したいと感じたあなたへ

Unity開発を効率よく進めるためには、実践的なスキルと仲間との交流が欠かせません。
そんな方におすすめのステップが、下記の3つです。

1. 有料教材「どこでもUnity教室」でゲーム制作を短期マスター

  • 5日でシンプルなFPS完成:初心者向けに要点を押さえたカリキュラム
  • C#や最新のInputSystem、FPS実装まで網羅:つまずきやすいポイントを先回りで解説
  • 購入特典:Discord招待+サンプルプロジェクトDLで、疑問や実装例を即確認

たった5日でFPSゲームが作れる自分に変わる教材はこちら
https://zenn.dev/ryuryu_game/books/fd28de9d8e963a

2. 無料コミュニティで、疑問をすぐに解消&モチベーションUP

  • 初心者~中級者までOK:学習進度に合わせて質問や情報共有
  • 質問サポートが充実:わからないことを仲間や講師に即相談
  • 学習仲間と切磋琢磨:一緒に学ぶから続けやすい

https://discord.gg/5FwuKCacNy

3. 実績豊富な“ゲーム開発所RYURYU”があなたをトータルサポート

  • コナラ総販売200件超:さまざまなUnity開発の依頼を対応
  • VR/AR/AIなど最新技術にも精通:幅広いノウハウを活かして開発支援
  • ゲームクリエイター甲子園や東京ゲームショウなど出展実績多数

https://coconala.com/users/1772507

Discussion