バーチャル3Dクリエイター神部まゆみです(*^_^*)
この記事はUnityでアイテム欄メニュー画面を作ってみた記事の続きです。
前回の記事はこちら。
やりたいこと:選択したアイテムの詳細説明文を表示する
前回の記事でメニュー画面のアイテムを一つ選択することができたので、詳細説明文を表示できるようにしたいですね。
ここまでくると結構ゲーム画面っぽくなってきた気がします。
ChatGPTパイセンに聞いてみる
とりあえず彼に聞けばなんとかなるだろう…。




アイテム詳細パネル良いですね。ScriptableObjectの項目を増やすんでしょうか?


いい流れです、その選択 👍
アイテム詳細パネル=ScriptableObjectを育てる工程なので、ここで設計しておくと後がめちゃくちゃ楽になります。
結論から言うと👇
✔ ScriptableObject の項目を増やします
✔ でも「最初から全部」はやらない
✔ 表示用データと挙動は分けて考える
① まず増やすべき最低限の項目
「詳細パネルに表示したいもの」だけでOKです。
ItemData(例)
using UnityEngine;
[CreateAssetMenu(menuName = "Game/Item")]
public class ItemData : ScriptableObject
{
[Header("Basic")]
public string itemName;
[TextArea]
public string description;
public Sprite icon;
[Header("Equip")]
public bool canEquip;
public int attackPower;
}
👉 これで
- 名前
- 説明文
- アイコン
- 装備可否
- 攻撃力
が全部表示できます。
② 詳細パネルは「表示専用」にする
ここ重要です。
ItemDetailPanel.cs
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class ItemDetailPanel : MonoBehaviour
{
[SerializeField] private Image icon;
[SerializeField] private TextMeshProUGUI nameText;
[SerializeField] private TextMeshProUGUI descriptionText;
[SerializeField] private GameObject equipInfo;
public void Show(ItemData item)
{
if (item == null)
{
gameObject.SetActive(false);
return;
}
gameObject.SetActive(true);
icon.sprite = item.icon;
nameText.text = item.itemName;
descriptionText.text = item.description;
equipInfo.SetActive(item.canEquip);
}
}
👉 ロジックは一切持たせない
表示だけ。
③ 選択時に詳細を更新する
ItemMenuController に1行足すだけ
[SerializeField] private ItemDetailPanel detailPanel;
public void SelectSlot(int index)
{
var item = slots[index].GetItem();
detailPanel.Show(item);
}
④ ScriptableObject を増やすときの考え方
ここ、めちゃくちゃ大事です。
❌ よくある失敗
- 効果処理まで全部 ItemData に書く
- if 文だらけ
✅ 正解の考え方
- ItemData = 定義・表示
- 使う処理 = 別クラス
後で👇が自然にできます。
- 回復アイテム
- 強化アイテム
- クエストアイテム
⑤ 今は不要なもの(後回しでOK)
- レアリティ
- 価格
- 使用効果
- ステータス補正
表示ができたら勝ちです。
⑥ ここまでできると
- スロット選択 → 詳細表示
- ScriptableObject 変更 → UIに即反映
- デザイナー作業も Inspector だけで完結
もう「ゲームっぽさ」が一気に出ます。
まとめ
- ✅ ScriptableObject に項目を追加
- ✅ 詳細パネルは表示専用
- ✅ 選択時に Show するだけ
- ✅ 最初は最低限でOK
実際に実装してみる
とりあえずいう通りに進めてみます。
この通りだと動かなかったので追加の設定とかも必要でした。
テキストメッシュプロで日本語が使えるように設定する
これやらないと □ みたいに表示されてしまうみたい。Unityエディターを日本語化していてもここは設定しないといけない。


↓の手順でフォントファイルを作り、テキストメッシュプロコンポーネントでフォント指定すれば良いみたい。


NotoSans JPが入ってなかったのでダウンロードする
ChatGPTがいうにはデフォルトで入ってるみたいなんだけどなかったのでダウンロードします。
Noto Sans Japanese – Google Fonts
展開してアセットフォルダにD&Dします。
フォントの上で右クリックしてテキストメッシュプロのSDFファイルを作成する。
これでテキストメッシュプロで使えるようになったみたいです。
ItemData.csを書き換える
ItemData.csを書き換える。
using UnityEngine;
[CreateAssetMenu(menuName = "Game/Item")]
public class ItemData : ScriptableObject
{
[Header("Basic")]
public string itemName;
[TextArea]
public string description;
public Sprite icon;
[Header("Equip")]
public bool canEquip;
public int attackPower;
}
これでアイテム説明欄が増えました。


まぁ適当に何か書いておいてくださいw


ItemDetailPanel.csを作る
ItemDetailPanel.csを作り、以下のコードをコピペする。
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class ItemDetailPanel : MonoBehaviour
{
[SerializeField] private Image icon;
[SerializeField] private TextMeshProUGUI nameText;
[SerializeField] private TextMeshProUGUI descriptionText;
[SerializeField] private GameObject equipInfo;
public void Show(ItemData item)
{
if (item == null)
{
gameObject.SetActive(false);
return;
}
gameObject.SetActive(true);
icon.sprite = item.icon;
nameText.text = item.itemName;
descriptionText.text = item.description;
equipInfo.SetActive(item.canEquip);
}
}
ItemMenuController.csを書き換える
ItemMenuController.csを書き換えます。
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++)
{
ItemData item = inventory.GetItem(i);
slots[i].SetItem(item);
}
}
}
これをコピペすると GetItem()がない というエラーが出るので、↓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}");
}
public ItemData GetItem()
{
return currentItem;
}
}
キャンバスにパネルをもう一つ追加、ItemDetailPanelをアタッチする
アイテム表示用のパネルを作り、ItemDetailPanel.csをアタッチします。
適当にサイズと位置を調整します。
説明パネルの子に画像やテキストメッシュプロを追加する
こんな感じで設定するみたいです。


こんな感じになった。


上で作ったフォントファイルをテキストに指定したり設定します。
MenuControllerにDetailPanelを追加
最後にこれをやらないとダメだった。


これで動いた!
これで無事に動きましたね。
文字の改行はRectTransformの幅で指定できる
改行が変な位置で入る場合はここで調整できます。
つづく?
無事に実装できて良かった。
だんだんゲームっぽくなってきましたね。
続きが書けたら追記します(*^_^*)




