インベントリ / メニューの項目を種類毎に変える

前回作成したItemDetailを削除。


新しくImageを作成し、ItemDetailと名付けます。


新しく空のオブジェクトを作成しbuttonsと名付け、VerticalLayoutGroupを追加する。


buttonsの子オブジェクトとしてButtonを作成し、menuButtonと名付けます。さらにImageのソース画像をmenuButtonを指定します。


このオブジェクトを「Inventory/Prefabs/」内に作成します。その後シーン上のmenuButtonを削除します。そのあと「Inventory/Demo/Scripts/」フォルダに新しくItemDetailDemo2スクリプトを作成してください。
ItemDetailDemo2.cs
1using UnityEngine;
2using UnityEngine.UI;
3
4namespace FlMr_Inventory.Demo
5{
6    /// <summary>
7    /// ItemDetailの動作確認のためのクラス
8    /// アイテムに応じたボタンを表示
9    /// </summary>
10    public class ItemDetailDemo2 : ItemDetailBase
11    {
12        [SerializeField] private Button buttonPrefabs;
13        [SerializeField] private Transform buttonsTrn;
14
15        protected internal override void OnClickCallback
16            (ItemBag itemBag, ItemBase item, int number, GameObject slotObj)
17        {
18            // 元々あったボタンをすべて削除
19            foreach (Transform trn in buttonsTrn)
20            {
21                Destroy(trn.gameObject);
22            }
23
24            // IUsableなアイテムがクリックされたときに表示するボタン
25            if (item is IUsable usable)
26            {
27                var button = Instantiate(buttonPrefabs, buttonsTrn);
28            }
29
30            // IDeletableなアイテムがクリックされたときに表示するボタン
31            if (item is IDeletable)
32            {
33                var button = Instantiate(buttonPrefabs, buttonsTrn);
34            }
35        }
36    }
37}
全てのスクリプトが保存されていることを確認し、Unityに戻ります。
ItemDetailオブジェクトをItemBagのコンポーネントの変数に登録してください。


アイテムをクリックすると、種類に応じて表示されるボタンが変化することが分かります。


次に、このシステムの利用者、又は未来の自分が機能の心臓部を誤って触れないように守りましょう。
「Inventory/」フォルダ直下に移動してください。ここで右クリックから「Create/Assembly Definition」を選択します。


ここで使用する名前は、読者様の好きなものを付けてください(「"""読者様を表す数文字""".Inventory」とかが良いと思います)。
このファイルを生成したことによりこのフォルダ内のスクリプトは、(設定しない限り)外のスクリプトに影響を与えないことが保証されます。
ところで、現在コンパイルエラーが生じているはずです。これはTextMeshProUGUIというクラスを参照できないという意味のエラーです。


外のスクリプトに影響を与えない、とはつまり外のスクリプトを使用できないことを意味します。そのためTextMeshProUGUIが使用できなくなったわけです。そこでTextMeshProUGUIは特別に使用を許可しましょう。作成したAssemblyDefinitionを選択し、インスペクター上で「TextMeshPro」モジュールの参照を許可します。下図の操作を行ってください。


操作を終えたら、忘れずに「Apply」ボタン(インスペクターの一番下)をクリックして下さい。これでエラーは解決します。以上でインベントリシステムに関する作業は終了です。今まで名前空間として「FlMr_Inventory」としていましたが、折角ですから「"""読者様を表す数文字"""_Inventory」などと変更しましょう。スクリプト上で名前空間にハイライトをあて、「Ctrl + R + R」又は「F2」キーで一括変更が可能です。

では、次がシステム面では最後の作業となります。いままでアイテムを「右クリック/Create/Item/」から作成してきました。ここで作成できるアイテム(HealingItemなど)はこのプロジェクト特有の物であり、今後このシステムを使う人間(将来の自分も含めて)にとっては邪魔でしかありません。そのためItemBaseサブクラスの[CreateAssetMenu...]の行を削除します。具体的にはの三つのクラスから削除してください。

次に「Inventory/Demo/Items/」にある「Resources/」フォルダは削除してください。


そして「Resources/」フォルダ内にあるItemUtilityはシングルトンなクラスであるため、インスタンスは唯一である制約を受けています。それにもかかわらずDemoのためのインスタンスを残しておくと、このシステムのユーザーが新たに作成することが出来なくなるためです。



ここからはpackage managerからこのシステムをいつでも呼び出せるようにします。機能の追加などは行いませんので、パッケージ化の部分は頂いても構いません。その場合、次のように作成したフォルダを残しておくと良いと思います。


パッケージ化を行わない場合

パッケージ化の部分を飛ばす方のみ、次の操作を行ってください。

「Inventory/Demo/Items/」の中の「Reources/」を削除します。次にAssetsフォルダをファイルエクスプローラーで開き「Inventory」フォルダのコピーを保管しておきます。


今後インベントリシステムが必要になった際は、このフォルダをD&Dするだけで使用出来るようになります。


インベントリシステムのパッケージ化

ここではgithub(gitコマンド)が必要になるため、アカウントなどの準備をお願いします。
まずは新しくpublicリポジトリを作成してください。


まずルートディレクトリに「package.json」ファイルを作成します。雛形は次の通りです。
package.json
1{
2    "name": "com.flmr.inventory",
3    "version": "1.0.0",
4    "displayName": "Original Inventory System",
5    "description": "original inventory system",
6    "unity": "yyyy,x",
7    "dependencies": {
8        "com.unity.textmeshpro" : "3.0.6"
9    },
10    "license": "MIT",
11    "author": {
12      "name": "flamari",
13      "email": "mirochacha_u_u_1106@yahoo.co.jp"
14    }
15}
名前の部分や説明、Unityのバージョンは適宜変更してください。

ではUnityの「Assets/Inventory/の中身」をコピーしてリポジトリのルートディレクトリ(package.jsonと同じ層)に複製してください。


これで準備は完了です。リモートリポジトリにpushしてください。

これで、リポジトリのURLがあれば、パッケージマネージャーからインベントリシステムをインポートできるようになりました。Unityで他のプロジェクトを開き、インポートできるか試してみましょう。パッケージマネージャーを開き、左上の「+」から「Add package from git url」を選択します。



出てくる小窓にgit urlを入力します。うまくいくとパッケージマネージャーからインベントリシステムがインポートされます。






今回は以上です。以降はデモンストレーション+αになるため、インベントリシステムの作成はここで終了になります。ここまで読んでいただきありがとうございました。
ここまでの状況は  Github から確認できます。