Unityでアイテム欄メニュー画面を作ってみたメモ⑥捨てたアイテムを落とす機能を作る

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

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

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

前回の記事はこちら。

●PRスペース●
■PR■

現在、ローポリ建物系・キャラクター系アセットが最大98%オフでまとめ買いできる Unity Awardsパブリッシャーバンドルセール をやってるみたいです(2026/01/21まで)。

Unity Awardsパブリッシャーバンドルセール 最大98%オフ

特にSyntyのアセットはローポリ低容量のため、VRChatワールド作成やモバイル向けゲーム作成などに使いやすいのでお勧めです。

〇まゆみマート|BOOTH

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

やりたいこと:捨てたアイテムを落とす

前回アイテムを捨てる処理を実装したので、捨てたアイテムを落とす処理を作りたいですね。

Fallout4だと捨てて落としたアイテムを解体したりできたけど…さすがにそこまでは作らないかな(^_^;)

ChatGPTパイセンに聞いてみる

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

unity アイテム 落とす インベントリ
神部まゆみ
神部まゆみ

次は落とす処理を実装したいです。
落とすには3Dモデルを用意する必要があると思いますが、とりあえずはざっくり回復系、武器系などのくくりで共通の3Dモデルを指定すればいいかなと思います。これはアイテムデータのScriptableObjectに項目を増やして3Dモデルを指定できるようにすれば管理しやすいでしょうか?
とりあえず捨てたアイテムを落とすスクリプトをお願いします。

ChatGPT
ChatGPT

その考え方、めちゃくちゃ良いです。
「共通モデル → 前方に出現 → 重力でコトッ」
TPSとして正解の体験設計だと思います 👍

結論から言うと👇
👉 はい、ItemData(ScriptableObject)に“落とす用Prefab”を持たせるのが最も管理しやすい
そして今の構成と相性も最高です。


全体設計(まずここが大事)

役割はこう分けます👇

要素役割
ItemData落とすPrefabを保持
DroppedItemワールドに存在するアイテム
ItemDetailPanel捨てる指示を出す
Inventoryデータ削除
DropItemSpawner実際に前方に生成

① ItemData に「落とす用Prefab」を追加

ItemData.cs 

using UnityEngine;

[CreateAssetMenu(menuName = "Game/Item")]
public class ItemData : ScriptableObject
{
    public string itemName;
    public Sprite icon;
    [TextArea]
    public string description;

    [Header("World Drop")]
    public GameObject dropPrefab;
}

👉

  • 回復系:薬瓶Prefab
  • 武器系:武器箱Prefab
    など 共通でOK です。

② 落とされたアイテム用スクリプト

DroppedItem.cs

using UnityEngine;

public class DroppedItem : MonoBehaviour
{
    public ItemData itemData;

    public void Setup(ItemData data)
    {
        itemData = data;
    }
}

③ 前方に落とす処理(Spawner)

DropItemSpawner.cs

using UnityEngine;

public class DropItemSpawner : MonoBehaviour
{
    [SerializeField] private Transform player;
    [SerializeField] private float forwardDistance = 1.2f;
    [SerializeField] private float heightOffset = 0.5f;

    public void Drop(ItemData item)
    {
        if (item == null || item.dropPrefab == null) return;

        Vector3 spawnPos =
            player.position +
            player.forward * forwardDistance +
            Vector3.up * heightOffset;

        GameObject obj = Instantiate(item.dropPrefab, spawnPos, Quaternion.identity);

        var dropped = obj.GetComponent<DroppedItem>();
        if (dropped != null)
        {
            dropped.Setup(item);
        }
    }
}

④ Prefab 側の必須構成

dropPrefab(共通でOK)

  • Mesh / Model
  • Collider
  • Rigidbody(Use Gravity ON)
  • DroppedItem.cs

👉 これで「コトッ」と落ちます。


⑤ ItemDetailPanel に組み込む

ItemDetailPanel.cs(変更部分のみ)

[SerializeField] private DropItemSpawner dropSpawner;
public void OnClickDrop()
{
    if (currentItem == null) return;

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

⑥ Inspector 設定チェック

ItemDetailPanel で👇

  • Inventory → プレイヤーの Inventory
  • MenuController → ItemMenuController
  • DropSpawner → DropItemSpawner(空オブジェクト)

DropItemSpawner 側で👇

  • Player → プレイヤー Transform

⑦ これで起きる挙動

  • メニューで「捨てる」
  • プレイヤー前方・空中に出現
  • Rigidbody で落下
  • ワールドに残る

「あ、捨てたな」感がちゃんと出ます。


拡張がめちゃくちゃ楽な構成です

このまま👇が自然にできます。

  • 拾う(DroppedItem → Inventory)
  • レア度で色変更
  • 落とせないアイテム
  • エフェクト追加

結構簡単にできそう?

まぁやってみます。

実際に実装してみる

彼の言う通りやってみます。

これまで割とサクッと進んだのでたぶんできると思います。

ItemData.csを書き換える

ItemData.cs に3Dオブジェクト用のパラメーターを追加します。

using UnityEngine;

[CreateAssetMenu(menuName = "Game/Item")]
public class ItemData : ScriptableObject
{
public string itemName;
public Sprite icon;
[TextArea]
public string description;

[Header("World Drop")]
public GameObject dropPrefab;
}

これでDrop Prefabという項目が増えたので、ここに指定した3Dモデルのプレハブが落ちます。

unity アイテム 落とす インベントリ

Drop Prefabに指定するプレハブの必須項目

3Dオブジェクトならメッシュレンダラーかスキンメッシュレンダラーは自動で追加されてるのでMesh/ModelはOK。

落とすためにコライダーとリジッドボディが必要で、後述のDroppedItem.csスクリプトもアタッチしておく必要がある。

unity アイテム 落とす インベントリ

プレハブの作り方

とりあえず3Dモデルをシーンに配置して設定し、

コライダーの大きさを設定して、

適当なフォルダにD&Dして、シーンに配置したオブジェクトは削除すればOK。

プレハブを再度編集したい場合は、プレハブファイルを選択してインスペクターの「開く」を押せばOK。

コライダーの黄緑色ギズモが表示されない場合はこちらを参照。

作ったプレハブをItemDataのScriptableObjectに指定する

作ったプレハブはここに指定します。

unity アイテム 落とす インベントリ

シーンにあるプレハブにしたオブジェクトは削除し、プロジェクトフォルダにD&Dしたプレハブを指定しないと不具合が出る可能性があるみたいなので注意。

DroppedItem.cs を追加

以下のコードをコピペしてDroppedItem.csを作ります。

using UnityEngine;

public class DroppedItem : MonoBehaviour
{
public ItemData itemData;

public void Setup(ItemData data)
{
itemData = data;
}
}

DropItemSpawner.cs を追加

プレイヤーの前方に落とす DropItemSpawner.cs を追加します。

using UnityEngine;

public class DropItemSpawner : MonoBehaviour
{
[SerializeField] private Transform player;
[SerializeField] private float forwardDistance = 1.2f;
[SerializeField] private float heightOffset = 0.5f;

public void Drop(ItemData item)
{
if (item == null || item.dropPrefab == null) return;

Vector3 spawnPos =
player.position +
player.forward * forwardDistance +
Vector3.up * heightOffset;

GameObject obj = Instantiate(item.dropPrefab, spawnPos, Quaternion.identity);

var dropped = obj.GetComponent<DroppedItem>();
if (dropped != null)
{
dropped.Setup(item);
}
}
}

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;

    [SerializeField] private DropItemSpawner dropSpawner;

    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;

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

空のオブジェクトを追加、ItemDetailSpawnerコンポーネントを追加して設定

指定するのはプレイヤーオブジェクトだけ。

ItemDetailPanelにItemDetailSpawnerを付けたオブジェクトを追加

DropSpawnerって項目が増えているので、DropItemSpawnerコンポーネントを追加したオブジェクトを追加します。

unity アイテム 落とす インベントリ

これで無事に落とせた!

これでちゃんと落ちましたね。

案外ここまで実装してあるゲーム少ないから、結構ゲームっぽくなってきたかな?

つづく?

案外手軽に実装できて良かった。

次は拾う処理を作ってみたいかな。

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

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