「Unity」アイテム取得状態をList<T>で管理するスクリプトを作ろう!

![スクリーンショット 2023-07-21 121213.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116324/cd3b17c6-9c21-8001-2f02-c9b3959bc5a1.png)
作成日 2023/07/14～2023/09/01
# はじめに

**プレイヤーがアイテムに触れるとアイテムが消え、所持アイテム数が増える。
そして、ゲーム中に1度しか反応しないし、その後取得したシーンに戻っても出現しなくなるスクリプト。**
\\\\\\\ほしい!!!/////
となったのでついでに記事を書きました！
初心者なのでお見苦しいところなどがあると思いますがどうぞよろしくお願いいたします！

# 使用した環境
Unity 2021.3.4f1
Visual studio 2022

# 目次
[1.調べた情報について・使う物の一覧](#1-調べた情報について使う物の一覧)
[2.その1.Itemloggerクラスの作成](#2-その1itemloggerクラスの作成)
[3.その2.Itemクラスの作成](#3-その2itemクラスの作成)
[4.まとめ](#4-まとめ)


# #1. 調べた情報について・使う物の一覧
C#のList< T > クラスを使っていきます！

### Q.後ろに付いてる< T >ってなんだろう? 
A.``ジェネリッククラス``のことです!
特定のデータ型に固有ではない操作をカプセル化するらしいです。
詳しくは公式をご覧ください!↓


https://learn.microsoft.com/ja-jp/dotnet/csharp/programming-guide/generics/generic-classes

今回は``List``内の3つのメソッドを使います。
1.**Add()**
2.**Contains()**
3. **Clear()** 

`List`は`List<型名> 変数名 = new List<型名>();`で作成します。
これを使うことによりアイテムなどのゲーム中に**保存したい物の管理** がしやすくなります。
(保存はStaticのおかげです。staticがないとシーンが変わると消えます!注意!)
**Listの初期化見本**

```C#:List
//string以外にもintなどが利用できます。
static List<string> parts = new List<string>();
```
`Add`は`リスト名.Add(変数名or"名前");`で使います。
リストに**アイテムを追加する**ためのメソッドです。これを使えば、リストに新たな要素を簡単に追加することができます。

**Add部分作成の見本**
```C#:List:Add
   //ゲットしたアイテムを記録
    public static void Add(string GetitemID)
    {
        if (Contains(GetitemID))
        {
            return;
        }
        parts.Add(GetitemID);//partsにはList名を書く
    }
```
Containsは`リスト名.Contains(変数名or"名前"など);`で使います。
リストが**特定のアイテムを含んでいるか**どうかを確認するためのメソッドです。これにより、特定のアイテムが既にリスト内に存在するかどうかを簡単にチェックすることができます。
**Contains部分作成の見本**

```C#:List:Contains
 //アイテムをゲットしたか確認
    public static bool Contains(string CheckItemID)
    {
        return parts.Contains(CheckItemID);
    }
```

</details>

Clearは[リスト名.Crler();]で使います。
リスト内の全てのアイテムを削除し、**リストを空にする**ためのメソッドです。これを使えば、一度に全てのアイテムを削除し、リストを初期状態に戻すことができます。
**Clearの見本**

``` C#:List:Clear
 //アイテム数をクリア
    public static void Clear()
    {
        parts.Clear();
    }
```
:::note warn
警告
リストに入っている記録を全部削除するので使いどころには注意が必要です。
:::


それでは早速やっていきましょう！
## #2. その1.ItemLoggerクラスの作成
アイテムを管理するスクリプトを作ります。
名前は``ItemLogger``です。
**このスクリプトはオブジェクトにアタッチする必要はないです。**

まずはアイテムを記憶する``List``の部分を作っていきます。
これが今回の大部分といっていいぐらいの大きなものです!(文は短いですけどね)
``String``以外にも``int``だったり、``両方組み合わせて``使うこともできます。

あと、``Count``を他のスクリプト内で呼び出したりすると現在持ってるアイテムをIF文で比較したりできます。
```C#:ItemLogger:ItemLogger
 public static  class ItemLogger
{
 static List<string> parts = new List<string>();
   //リスト内の数をintで召喚出来る
    //if文等で使える
    public static int Count => parts.Count;
```
次に、いつでもリスト内のアイテム記録を削除できるように「Clear」の部分を作っていきます。
これを呼び出すと、そのリスト内の記録を綺麗さっぱり削除してくれます。

``` C#:ItemLogger:Clear
 public static void Clear()
    {
        parts.Clear();
        //アイテム数をクリア
    }
```
そして、アイテムを取得した際にリストに追加できる``add``の部分を作っていきます。
```C#:ItemLogger:Add
    public static void Add(string GetitemID)
    {
        if (Contains(GetitemID))
        {
            //取得状態は追加するタイミングでもチェック!
            return;
        }
        parts.Add(GetitemID);
        //ゲットしたアイテムを記録
    }
```
## #3. その2.Itemクラスの作成
アイテム側にアタッチするスクリプトを作っていきます！
名前は``Item``です。

オブジェクト個々にID名を設定できるようにSerializeFieldを使います。
これを使うと、``01.01``(1ステージ.1個目)のような形で管理することができます。
```C#:Item:Item
public class Item : MonoBehaviour
{
    [SerializeField] string ID;
```

次にシーンが読み込まれた時の部分を作っていきます。
ステージが読み込まれた際にアイテム獲得済みかを``ItemLogger``側に聞きに行く感じです。
``ID``の中は上の``01``(int)や``item1``(string)のようなListで設定した変数名が使えます。

```C#:Item:Start
    void Start()
    {
        //初期化 取得状態の確認
        if (ItemLogger.Contains(ID))
        {
            Debug.Log("アイテムを獲得済み");
            Destroy(gameObject);
        }
        else
        {
            Debug.Log("アイテムを獲得してないよ");
        }
    }
```
次にアイテムに触った時の処理を書きます。
まず、タグをプレイヤーか確認します。
プレイヤーの場合は取ったアイテムのIDを``ItemLoggerに追加``します。
その後``Destroy``でプレイヤーが取得したアイテムを削除します。
```C#:Item:OnTriggerEnter2D
 private void OnTriggerEnter2D(Collider2D other)
    {
        //プレイヤーがアイテムを獲得したら
        //IDをItemLoggerにIDを送ってアイテムを消す。
        if(other.CompareTag("Player"))
        {
            ItemLogger.Add(ID);
            Destroy(gameObject);
        }
    }
```
これでアイテムにアタッチするスクリプトができました！
ではアイテムオブジェクトにアタッチ！
あっ!そうそう! **IDを設定**するのを忘れずにしておきましょう。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116324/9c38ec21-c415-f396-2572-efbb19f4b8d4.png)
![m2gj7-u8pc4.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3116324/95fc3ac7-17f1-9526-2c72-40b7921522f7.gif)
このような感じに使うこともできます!





## #4. まとめ
``Add、Contains、Clear``
これら3つのメソッドを使えば、リスト内のアイテム管理はいい感じです!




###### #雑談
アイテム管理以外にも汎用性がよさげな物なので作り方次第では他のスクリプトにも使えるかも...?
それ以外のメソッドも確認ぐらいはしておきましょう!!
~~掘り出し物は探さなければ見つからないのですから...~~


# 参考元
[(List説明の参考元)マイクロソフト公式リンク #C Listクラス](https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.list-1?view=net-7.0)

https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.list-1?view=net-7.0