スポンサーリンク

【Unity】ScriptableObjectでゲーム内アイテムを管理する方法

Unity

Unity Version 2021.3.11f1(LTS)

アイテムの情報を持ったScriptableObjectを作成する

まずは、アイテムのデータを設定するための、ScriptableObjectを作成していきます!

ScriptableObjectの詳しい説明は、以下の記事で紹介しています。

アイテム管理用ScriptableObject

using System.Collections;
using System.Collections.Generic;
using UnityEngine;


    //アイテムの種類(列挙体)
    public enum ItemType 
    {
        MATERIAL = 0,   //素材
        TOOL = 1,       //道具
        WEAPON = 2,     //武器
    }

//アイテムのソースデータ
[CreateAssetMenu(menuName = "BlogAssets/ItemSourceData")]
public class ItemSourceData : ScriptableObject
{
    //アイテム識別用id
    [SerializeField] private string _id;
    //idを取得
    public string id
    {
        get { return _id; }
    }

    //アイテムの名前
    [SerializeField] private string _itemName;
    //アイテム名を取得
    public string itemName
    {
        get { return _itemName; }
    }

    //アイテムの種類
    [SerializeField] private ItemType _itemType;
    //アイテムの種類を取得
    public ItemType itemType
    {
        get { return _itemType; }
    }

    //アイテムの見た目
    [SerializeField] private Sprite _sprite;
    //アイテムの見た目を取得
    public Sprite sprite 
    {
        get { return _sprite; }
    }

    //買値
    [SerializeField] private int _buyingPrice;
    //買値を取得
    public int buyingPrice
    {
        get { return _buyingPrice; }
    }

    //売値
    [SerializeField] private int _sellingPrice;
    //売値を取得
    public int sellingPrice
    {
        get { return _sellingPrice; }
    }
}

このスクリプトでは、アイテムのソースデータを管理するためのScriptableObjectを定義しています。

アイテムの種類

//アイテムの種類(列挙体)
public enum ItemType 
{
    MATERIAL = 0,   //素材
    TOOL = 1,       //道具
    WEAPON = 2,     //武器
}

アイテムの種類は、Enum(列挙体)を使って判断するようにしています!

変数の定義

//アイテム識別用id
[SerializeField] private string _id;
//idを取得
public string id
{
      get { return _id; }
}

変数の定義は、外部のスクリプトから値の書き換えが出来ないように、privateで定義しています。Inspector上では、値を編集したいので、[SerializeField]を変数の先頭に記述しておきます!

外部のスクリプトからは、値の取得だけはしたいので、getterを定義して値を取得できるようにしておきます。

アイテム情報アセットを作成する

ScriptableObjectのクラスを定義したら、アイテムデータアセットを作成していきます!

Projectウィンドウで右クリックして、Create → BlogAssets → ItemSourceDataを選択します。

画像のような、ScriptableObjectのアセットが作成されます。

それぞれ、道具、素材、武器のデータを作成しました!

アイテムのデータ作成はこれで終了です!

アイテムのソースデータを管理するマネージャーを作る

ItemManagerクラス

using System.Collections.Generic;
using UnityEngine;
using System.Linq;

//アイテムデータ
public class ItemData
{
    public string id;   //アイテムid

    private int count;  //所持数

    //コンストラクタ
    public ItemData(string id, int count = 1)
    {
        this.id = id;
        this.count = count;
    }

    //所持数カウントアップ
    public void CountUp(int value = 1)
    {
        count += value;
    }

    //所持数カウントダウン
    public void CountDown(int value = 1)
    {
        count -= value;
    }
}

//アイテム管理クラス
public class ItemManager : MonoBehaviour
{
    [SerializeField] private List<ItemSourceData> _itemSourceDataList;  //アイテムソースリスト

    private List<ItemData> _playerItemDataList = new List<ItemData>();  //プレイヤーの所持アイテム


    private void Awake()
    {
        LoadItemSourceData();
    }

    //アイテムをロードする
    private void LoadItemSourceData() 
    {
        _itemSourceDataList = Resources.LoadAll("ScriptableObject", typeof(ItemSourceData)).Cast<ItemSourceData>().ToList();
    }

    //アイテムソースデータを取得
    public ItemSourceData GetItemSourceData(string id) 
    {
        //アイテムを検索
        foreach(var sourceData in _itemSourceDataList) 
        {
            //IDが一致していたら
            if(sourceData.id == id)
            {
                return sourceData;
            }
        }
        return null;
    }


    //アイテムを取得
    public void CountItem(string itemId, int count)
    {
        for (int i = 0; i < _playerItemDataList.Count; i++)
        {
            //IDが一致していたらカウント
            if (_playerItemDataList[i].id == itemId)
            {
                _playerItemDataList[i].CountUp(count);
                break;
            }
        }

        //IDが一致しなければアイテムを追加
        ItemData itemData = new ItemData(itemId, count);
        _playerItemDataList.Add(itemData);
    }
}

ItemManagerでは、アイテムのソースデータを管理しています。

アイテムのソースデータを使いたい時は、このクラスにアクセスして、データを取得することが出来ます!

ItemDataクラス

//アイテムデータ
public class ItemData
{
    public string id;   //アイテムid

    private int count;  //所持数

    //コンストラクタ
    public ItemData(string id, int count = 1)
    {
        this.id = id;
        this.count = count;
    }

    //所持数カウントアップ
    public void CountUp(int value = 1)
    {
        count += value;
    }

    //所持数カウントダウン
    public void CountDown(int value = 1)
    {
        count -= value;
    }
}

ItemDataクラスでは、ゲーム内のアイテムのデータを管理します。

アイテムのソースデータとは別なので気を付けてください!

アイテムを取得したときの処理を実装する

using System.Collections.Generic;
using UnityEngine;

//プレイヤーを管理するクラス
public class PlayerManager : MonoBehaviour
{
    [SerializeField] private List<ItemData> _itemDataList = new List<ItemData>();   //プレイヤーの所持アイテム

    //アイテムを取得
    public void CountItem(string itemId, int count)
    {
        for (int i = 0; i < _itemDataList.Count; i++)
        {
            //IDが一致していたらカウント
            if (_itemDataList[i].id == itemId)
            {
                _itemDataList[i].CountUp(count);
                break;
            }
        }

        //IDが一致しなければアイテムを追加
        ItemData itemData = new ItemData(itemId, count);
        _itemDataList.Add(itemData);
    }
}

PlayerManagerクラスでは、所持しているアイテムを管理しています。

CountItem関数は、アイテムを取得したときに呼ぶことで、取得したアイテムデータを保存することが出来ます。

これで、アイテムを拾ったり、購入したときに、アイテムの所持数を更新することが出来ます!

アイテムを使用したときの処理を実装する

using System.Collections.Generic;
using UnityEngine;

public class PlayerManager : MonoBehaviour
{
    [SerializeField] private List<ItemData> _itemDataList = new List<ItemData>();   //プレイヤーの所持アイテム

    //アイテムを取得
    public void CountItem(string itemId, int count)
    {
        //List内を検索
        for (int i = 0; i < _itemDataList.Count; i++)
        {
            //IDが一致していたらカウント
            if (_itemDataList[i].id == itemId)
            {
                //アイテムをカウント
                _itemDataList[i].CountUp(count);
                return;
            }
        }

        //IDが一致しなければアイテムを追加
        ItemData itemData = new ItemData(itemId, count);
        _itemDataList.Add(itemData);
    }

    //アイテムを使用
    public void UseItem(string itemId,int count) 
    {
        //List内を検索
        for (int i = 0; i < _itemDataList.Count; i++)
        {
            //IDが一致していたらカウント
            if (_itemDataList[i].id == itemId)
            {
                //アイテムをカウントダウン
                _itemDataList[i].CountDown(count);
                break;
            }
        }
    }
}

UseItem関数は、アイテムを使用したときに呼ぶことで、使用したアイテムのデータを保存することが出来ます。

これで、アイテムを使ったり、売却したときにアイテムの所持数を更新することが出来ます!

ソースデータにあるアイテムの種類や金額は、ゲームに合わせて必要な時に使って下さい!

お疲れさまでした!

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