Unityでアイテム欄メニュー画面を作ってみたメモ③アイテムをカーソル選択して選択アイテムフレームの色を変える

Unity アイテム メニュー画面 作り方 インベントリ  3Dゲームの作り方
※記事内に広告が含まれています。

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

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

前回の記事はこちら。

●PRスペース●
■PR■

現在、リアル系環境アセットが50%オフで買える Unityパブリッシャーセール をやってるみたいです(2026/01/08まで)。

Unity パブリッシャーセール 50%オフ

クーポンコード SCANSFACTORY を使うと、↓の Abandoned Factory Buildings アセットがタダで貰えます(決済時にクーポンコード入力適用で0円に)。

無料アセットだけでも貰っておくと良いかも。

〇まゆみマート|BOOTH

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

やりたいこと:アイテムメニュー画面で特定のアイテムを選択できるようにする

前回インベントリのアイテムを表示することはできたけど、表示しただけなのでアイテムを選択したりはできない。

カーソルを実装しないといけないと思うけど結構大変なイメージ?

まぁChatGPTパイセンに聞けばなんとかなるか…。

ChatGPTパイセンに聞いてみる

とりあえず彼に相談すればなんとかなるだろう…。

Unity アイテム メニュー画面 作り方 カーソル 選択
神部まゆみ
神部まゆみ

インベントリのアイテム表示は無事に実装できました。 しかしまだ表示できただけです。
アイテムを選択するためにはカーソルが必要になるのではないでしょうか?しかも空のアイテム欄は飛ばせるようにするか、空のスロットならボタンを押しても無効だと判定したりしないといけません。結構大変そうなイメージですがすぐできるのでしょうか?

ChatGPT
ChatGPT

その不安、めちゃくちゃ分かります。
でも安心してください。思っているほど大変じゃないです。
むしろ今の構成だと「自然に」実装できます。

結論から言うと👇

✔ カーソルはもうある
✔ 空スロット判定も一瞬
✔ “選択できない”処理は UI 側だけで完結する

ひとつずつ見ていきましょう。


① カーソルは「もう用意できている」

実はあなた、もうカーソル周りはクリアしてます。

ポーズ中に👇をやってますよね?

Cursor.lockState = CursorLockMode.None;
Cursor.visible = true;

これだけで

  • マウスでスロットをクリックできる
  • UI の Button が反応する

👉 新しくカーソルを作る必要はありません。


② ItemSlot を「Button」として使う

やることはこれだけ

  • ItemSlot(親オブジェクト)に Button を付ける
  • ItemSlot スクリプトに「選択」処理を書く
public class ItemSlot : MonoBehaviour
{
    [SerializeField] private Image icon;
    private ItemData currentItem;

    public void SetItem(ItemData item)
    {
        currentItem = item;

        if (item == null)
        {
            icon.enabled = false;
            GetComponent<Button>().interactable = false;
            return;
        }

        icon.enabled = true;
        icon.sprite = item.icon;
        GetComponent<Button>().interactable = true;
    }

    public void OnClick()
    {
        if (currentItem == null) return;
        Debug.Log($"Selected: {currentItem.itemName}");
    }
}

✔ 空スロットは自動で押せなくなる
✔ 判定は UI 側だけ


③ 「空スロットを飛ばす」必要はない

ここ、安心ポイントです。

マウス操作の場合

  • 空スロットは interactable = false
  • そもそも選べない

ゲームパッド操作の場合(後回しでOK)

  • EventSystem が勝手にスキップしてくれる

👉 自前で「空を飛ばす」処理は書きません。


④ 選択状態の見た目もすぐできる

例:選択中フレーム表示

[SerializeField] private GameObject selectedFrame;

public void SetSelected(bool selected)
{
    selectedFrame.SetActive(selected);
}

選択管理は
ItemMenuController がやるのがきれいです。


⑤ どれくらい大変?

正直に言うと👇

  • UI構築:もう終わってる
  • カーソル:もうある
  • 空判定:3行
  • 選択処理:Button 1個

👉 半日もかからないレベルです。


⑥ 今やらなくていいこと

  • キーボード/ゲームパッド操作
  • 十字キー移動
  • スクロール

まずは
マウスで選べる=完成
でOKです。


まとめ

  • ✅ カーソルは既に出ている
  • ✅ Button を使えば選択は一瞬
  • ✅ 空スロットは interactable=false
  • ✅ 想像よりずっと簡単

え、もう実はカーソルを実装していたっぽい。

ChatGPTパイセンの言う通りにコピペしただけだから気付かなかったけど(^_^;)

実際に動かしてみる

とりあえず選択してクリックしてデバッグログを出すだけみたいだけど、まずはこれで動かしてみます。

ItemSlotにボタンを付ける

こんな構造になっているけど、親のItemSlotにボタンを付ければ良いっぽい。

Unity アイテム メニュー画面 作り方 インベントリ 

ItemSlot.csを書き換える

以下のスクリプトに書き換えます。

using UnityEngine;
using UnityEngine.UI;
public class ItemSlot : MonoBehaviour
{
    [SerializeField] private Image icon;
    private ItemData currentItem;

    public void SetItem(ItemData item)
    {
        currentItem = item;

        if (item == null)
        {
            icon.enabled = false;
            GetComponent<Button>().interactable = false;
            return;
        }

        icon.enabled = true;
        icon.sprite = item.icon;
        GetComponent<Button>().interactable = true;
    }

    public void OnClick()
    {
        if (currentItem == null) return;
        Debug.Log($"Selected: {currentItem.itemName}");
    }
}

ボタンのクリック時()にItemSlotのOnClick()メソッドを指定する

クリック時()の+ボタンを押して、ItemSlot自身を指定してItemSlot.OnClick()を指定します。

Unity アイテム メニュー画面 作り方 インベントリ 

EventSystemを追加する

これがないとクリック検知できません。

追加するだけでOK。

Unity アイテム メニュー画面 作り方 インベントリ 

これでクリック検知できた!

これで無事にクリック検知できましたね。

せっかくなので選択されたフレームを目立つようにする

これだけだと微妙だから、選択されたフレームを目立たせるところまでやりたいと思います。

ChatGPTパイセンに聞いたらそこまで難しくないっぽい?

Unity アイテム メニュー画面 作り方 インベントリ 

選択中用のフレーム画像を用意する

GIMPで適当に作りました。通常フレームよりちょっと大きく135pxにしてある。

Unity アイテム メニュー画面 作り方 インベントリ 

規約とか面倒なことは言わないので勝手に自由に使ってください。

あくまでテスト用なのでこのまま使うのは見栄え的におススメしませんが(^_^;)

FrameSelectedオブジェクト(Image)を追加

これが選択用のフレームになりますが、最初はインスペクターオフで非表示にしておく。

コピペしちゃってますが、位置がちゃんとあっているか確認してください。

コピペした場合、正常に動いていても赤いフレームがスロット1にしか表示されない、なんてことになりがちです(というかなった)。

場所をちゃんと確認しましょう。

ItemSlot.csを書き換える

ItemSlot.csを書き換えます。

ItemSlot.cs

using UnityEngine;
using UnityEngine.UI;
public class ItemSlot : MonoBehaviour
{
    [SerializeField] private Image icon;
    private ItemData currentItem;

    [SerializeField] private GameObject normalFrame;
    [SerializeField] private GameObject selectedFrame;

    public void SetSelected(bool selected)
    {
        normalFrame.SetActive(!selected);
        selectedFrame.SetActive(selected);
    }

    public bool HasItem()
    {
        return currentItem != null;
    }

    public void SetItem(ItemData item)
    {
        currentItem = item;

        if (item == null)
        {
            icon.enabled = false;
            GetComponent<Button>().interactable = false;
            return;
        }

        icon.enabled = true;
        icon.sprite = item.icon;
        GetComponent<Button>().interactable = true;
    }

    public void OnClick()
    {
        if (currentItem == null) return;
        Debug.Log($"Selected: {currentItem.itemName}");
    }
}

ItemMenuController.csを書き換える

こっちも書き換えます。

ItemMenuController.cs

using UnityEngine;

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

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

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

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

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

    void OnEnable()
    {
        Refresh();
    }

    public void Refresh()
    {
        for (int i = 0; i < slots.Length; i++)
        {
            ItemData item = inventory.GetItem(i);
            slots[i].SetItem(item);
        }
    }
}

ボタンのOnClick()にメソッドを追加

選択中のフレームを扱う、ItemMenuController.csのSelectSlotメソッドを追加します。

ItemSlot設定

ItemSlotに通常フレームと選択中フレームを設定する。

あとクリック時()に追加したメソッドの数字のところを書き換える。

スロット数は0から数えるのでスロット1からの場合は0、スロット2の場合は1に。

これで動いた!

これで無事に動きましたね。

つづく?

案外簡単にできて良かった。あとは選択中アイテムで「使う」「捨てる」とか出せたら良いかな?

とりあえずシステムさえ組めればあとは増やしていくだけで済みそうな気がする。

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

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