Unityでアイテム欄メニュー画面を作ってみたメモ⑤アイテムをインベントリから捨てる機能を作る

unity アイテム 捨てる インベントリ 3Dゲームの作り方
※記事内に広告が含まれています。

バーチャル3Dクリエイター神部まゆみです(*^_^*)

この記事はUnityでアイテム欄メニュー画面を作ってみた記事の続きです。

前回の記事はこちら。

●PRスペース●

〇まゆみマート|BOOTH

BOOTHでVRoidテクスチャやVRChat向けオブジェクトなどを販売しています。いいねしてくれると励みになります(*^-^*)

やりたいこと:アイテムを捨てる機能を作る

とりあえずアイテムの詳細を表示する機能は作れたので、次は捨てる処理を作りたい。

拾う機能はオブジェクトを作ったりしないといけないため、こちらのほうが先にできるっぽいのでやってみました。

ChatGPTパイセンに聞いてみる

とりあえず彼に聞けばなんとかなるだろう…。

unity アイテム 捨てる インベントリ
神部まゆみ
神部まゆみ

ここまで良い感じに実装できましたが、次は捨てるとか拾うとかですかね?
スペース的にアイテム詳細欄の近くの方が良いんでしょうか?というか項目が増えてきたのでそろそろ配置も考えないといけませんが

ChatGPT
ChatGPT

動いたとのこと、よかったです!🎉
ここまで来るともうUI設計フェーズに入ってます。かなりゲームっぽくなってきましたね。

次に何を作るか?(おすすめ順)

今の流れだと自然なのは👇

  1. 使う/装備する
  2. 捨てる
  3. 拾う(ワールド側)

なので、
👉 「捨てる」ボタンをアイテム詳細パネルに追加
が一番分かりやすくて実装もしやすいです。


「捨てる」の配置はどこが良い?

結論

**アイテム詳細欄の近く(下 or 右)**がベストです。

理由:

  • 「このアイテムに対する操作」だと直感的
  • Slot → Detail → Action の流れが自然
  • ボタンが増えても管理しやすい

おすすめUI構成(実用寄り)

[ アイテム一覧 ]    [ アイテム詳細 ]
[ □ □ □ □ □ ]    名前
[ □ □ □ □ □ ]    説明文
                   ----------
                   [ 装備する ]
                   [ 使う     ]
                   [ 捨てる   ]

※ 最初は
「装備」or「使う」+「捨てる」
の2つだけで十分です。


まず「捨てる」処理全体の役割分担(超重要)

整理するとこうです👇

クラス役割
ItemDetailPanel捨てるボタンを押す
Inventoryアイテムを削除する
ItemMenuControllerUIを更新する

① Inventory に「削除」処理を追加

Inventory.cs

using System.Collections.Generic;
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public List<ItemData> items = new List<ItemData>();

    public void Remove(ItemData item)
    {
        if (items.Contains(item))
        {
            items.Remove(item);
            Debug.Log($"Removed item: {item.itemName}");
        }
    }
}

② ItemDetailPanel に currentItem を持たせる

ItemDetailPanel.cs

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class ItemDetailPanel : MonoBehaviour
{
    [SerializeField] private Image icon;
    [SerializeField] private TMP_Text nameText;
    [SerializeField] private TMP_Text descriptionText;

    [SerializeField] private Inventory inventory;
    [SerializeField] private ItemMenuController menuController;

    private ItemData currentItem;

    public void Show(ItemData item)
    {
        if (item == null)
        {
            gameObject.SetActive(false);
            return;
        }

        currentItem = item;

        icon.sprite = item.icon;
        nameText.text = item.itemName;
        descriptionText.text = item.description;

        gameObject.SetActive(true);
    }

    public void Hide()
    {
        currentItem = null;
        gameObject.SetActive(false);
    }

    // ★捨てるボタン用
    public void OnClickDrop()
    {
        if (currentItem == null) return;

        inventory.Remove(currentItem);
        menuController.Refresh();
        Hide();
    }
}

③ Inspector で必須設定(ここ超重要)

ItemDetailPanel を選択して👇

  • Inventory → プレイヤーの Inventory をドラッグ
  • Menu Controller → ItemMenuController をドラッグ
  • Icon / NameText / DescriptionText を設定

④ 捨てるボタンを作る

ヒエラルキー

ItemDetailPanel
 └─ DropButton

DropButton

  • Button コンポーネントを追加
  • OnClick() に
    👉 ItemDetailPanel.OnClickDrop() を指定

⑤ ItemMenuController の Refresh()

すでにある前提ですが、念のため👇

public void Refresh()
{
    for (int i = 0; i < slots.Length; i++)
    {
        slots[i].SetItem(
            i < inventory.items.Count ? inventory.items[i] : null
        );
    }
}

⑥ 動作確認チェックリスト

✅ アイテムを選択
✅ 詳細パネルが表示
✅ 捨てるボタンを押す
✅ スロットから消える
✅ 詳細パネルが閉じる

ここまで動けば 100点 です。

そんなに難しくなさそうかなぁ。

まぁなんとかできそうな気がします。

実際に実装してみる

とりあえず闇雲に実装していきます。

Inventory.csを書き換える

プレイヤーにアタッチしているInventory.csを書き換えます。

using System.Collections.Generic;
using UnityEngine;

public class Inventory : MonoBehaviour
{
    public List<ItemData> items = new List<ItemData>();

    public void Remove(ItemData item)
    {
        if (items.Contains(item))
        {
            items.Remove(item);
            Debug.Log($"Removed item: {item.itemName}");
        }
    }
}

ItemDetailPanel.csを書き換える

アイテム説明欄のItemDetailPanel.csを書き換えます。

using UnityEngine;
using UnityEngine.UI;
using TMPro;

public class ItemDetailPanel : MonoBehaviour
{
    [SerializeField] private Image icon;
    [SerializeField] private TMP_Text nameText;
    [SerializeField] private TMP_Text descriptionText;

    [SerializeField] private Inventory inventory;
    [SerializeField] private ItemMenuController menuController;

    private ItemData currentItem;

    public void Show(ItemData item)
    {
        if (item == null)
        {
            gameObject.SetActive(false);
            return;
        }

        currentItem = item;

        icon.sprite = item.icon;
        nameText.text = item.itemName;
        descriptionText.text = item.description;

        gameObject.SetActive(true);
    }

    public void Hide()
    {
        currentItem = null;
        gameObject.SetActive(false);
    }

    // ★捨てるボタン用
    public void OnClickDrop()
    {
        if (currentItem == null) return;

        inventory.Remove(currentItem);
        menuController.Refresh();
        Hide();
    }
}

ItemMenuController.csを書き換える

GetItemのところでエラーが出ているはずなので、ここのRefreshを書き換えます。

using UnityEngine;

public class ItemMenuController : MonoBehaviour
{
    [SerializeField] private Inventory inventory;

    [SerializeField] private ItemSlot[] slots;
    private int selectedIndex = -1;

    [SerializeField] private ItemDetailPanel detailPanel;

    public void SelectSlot(int index)
    {
        if (!slots[index].HasItem()) return;

        if (selectedIndex >= 0)
            slots[selectedIndex].SetSelected(false);

        selectedIndex = index;
        slots[selectedIndex].SetSelected(true);

        var item = slots[index].GetItem();
        detailPanel.Show(item);

    }

    void OnEnable()
    {
        Refresh();
    }

    public void Refresh()
    {
        for (int i = 0; i < slots.Length; i++)
        {
            slots[i].SetItem(
                i < inventory.items.Count ? inventory.items[i] : null
            );
        }
    }
}

ItemDetailPanelを設定する

↓InventoryとMenuControllerを指定するところが新しく追加されたので指定します。

unity アイテム 捨てる インベントリ

捨てるボタンを作ってOnClick()から処理を呼び出す

UIで捨てるボタンを作り、OnClick()からItemDetailPanelのOnClickDrop()メソッドを呼びます。

あとボタンのテキストと位置を適当に整えます。

unity アイテム 捨てる インベントリ

これで動いた!

これで無事に捨てられましたね。

「本当に良いですか?」みたいなメニューも作ろうかと思ったけど…できればアイテムを落とす処理も作りたいからなくていいかな…。

まぁ後で考えます。

捨てたらフィールドに落とす方式もやりたいけどオブジェクトを用意しないと…

Fallout4だと持ち物を捨てて落ちたオブジェクトを解体とかやってたな…。

でもアイテムとセットで3Dオブジェクトも必要になるんですよね(^_^;)

とりあえず拾う処理を作ってから考えます。

つづく?

案外簡単に実装できて良かった。

メニューはある程度完成してきたからちょこっと改変するだけで結構実装できそうですね。

また続きが書けたら追記します(*^_^*)

タイトルとURLをコピーしました