敵や装備みたいな、バリエーションがたくさんあるものは、どうやって作ればいいの??
本記事の内容
・データベースとはなにか?
・データベースScriptableObjectを使おう
同系統のバリエーションを増やすにはScriptablObjectを使おう!
ScriptablObjectを使って、設定値をまとめて管理しよう!
ゲームを作っていると、敵・アイテム・装備・スキルなど、同じような機能を持ったパラメータ違いのオブジェクトが複数必要になることがあります。
ポケモンを例にすると、「モンスターボール」、「スーパーボール」など捕獲率のパラメータ違いのアイテムが出てきますよね。このように同じ系統のオブジェクトを複数管理するのに適したUnityの機能が「ScriptableObject」です。
たとえば、「モンスターボール」・「スーパーボール」・「きずぐすり」・「まんたんのくすり」、というアイテムをゲームに実装するとします。
これらのアイテムには以下のパラメータを持たせるとします。
- アイテムID(こういったリストを作るときには、IDがあるとなにかと便利)
- アイテムのアイコン
- アイテムの種類
- アイテムの名前
- アイテムの説明
- 効果値(例えばモンスターボールなら50%、スーパーボールなら70%、きずぐすりなら20、まんたんのくすりなら999)
すると、以下のような表が出来上がります。
ID | アイコン画像 | 種類 | 名前 | 説明 | 効果値 |
100 | ボール | モンスターボール | 低確率で捕まえる | 50 | |
101 | ボール | スーパーボール | 中確率で捕まえる | 70 | |
200 | 回復 | きずぐすり | HPを20回復する | 20 | |
201 | 回復 | まんたんのくすり | HPを満タンまで回復する | 999 |
これらをUnity内で管理できるのが、ScriptableObjectです。
ScriptablObjectのサンプル
実際にこれらのアイテムをUnity内で使う方法を解説してきます。
スクリプトファイルを作って、以下サンプルのコードを貼り付けます。
using UnityEngine;
// アイテムの種類を表す列挙型
public enum ItemType
{
Ball, // ボール
Heal // 回復
}
[System.Serializable]
public class Item
{
public int id; // アイテムのID
public Sprite icon; // アイテムのアイコン画像
public ItemType itemType; // アイテムの種類
public string itemName; // アイテムの名前
[TextArea]
public string description; // アイテムの説明
public int effectValue; // 効果値
}
[CreateAssetMenu(fileName = "ItemList", menuName = "Inventory/ItemList")]
public class ItemList : ScriptableObject
{
public Item[] items;
/// <summary>
/// 指定されたIDのアイテムを返す
/// </summary>
/// <param name="id">検索するアイテムのID</param>
/// <returns>該当するアイテム。見つからなければnull。</returns>
public Item GetItemById(int id)
{
foreach (var item in items)
{
if (item.id == id)
{
return item;
}
}
Debug.LogWarning($"Item with ID {id} not found.");
return null;
}
}
ScriptableObjectは通常のC#のスクリプトとは書き方が違います。
特徴としては、冒頭に[CreateAssetMenu(...)]とあるところです。
これはScriptablObjectを作るためのメニューを設定するというコードです。このコードによって、プロジェクトビューで右クリックすると、ScriptablObjectを生成することが出来ます。
また、ScriptablObjectには、メソッドを入れ込むことが出来ます。GetItemByID
メソッドでは、IDを渡すとそれに該当するItemのデータを返してくれるメソッドです。
Step1のスクリーンショットにあるメニューからScriptablObjectが作成されると、以下のような青い箱が表示されます。
これが、ScriptablObjectです。ここに設定値を登録します。
先程の例にあるような設定値を登録します。
これらのScriptablObjectが設定出来たら、最後にScriptablObjectで設定した値を取得する方法です。
今回はサンプルとして、ScriptablObjectから値を取得し、UIに表示するスクリプトを作ってみます。
新規でスクリプトを作成し、以下のコードを作りました。
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class SampleItemDataSetter : MonoBehaviour
{
[SerializeField] private ItemList itemList; // ScriptableObjectをアタッチ
[SerializeField] private Image itemIconImage; // アイコン表示用
[SerializeField] private int itemId; // 表示したいアイテムのID
[SerializeField] private TMP_Text itemNameText; // アイテム名表示用
[SerializeField] private TMP_Text itemDescriptionText; // 説明表示用
[SerializeField] private TMP_Text itemEffectValueText; // 効果値表示用
private void Start()
{
DisplayItemDetails(itemId);
}
private void DisplayItemDetails(int id)
{
// IDに該当するアイテムを取得
var item = itemList.GetItemById(id);
if (item != null)
{
itemIconImage.sprite = item.icon;
itemNameText.text = item.itemName;
itemDescriptionText.text = item.description;
itemEffectValueText.text = $"Effect: {item.effectValue}";
}
}
}
ヒエラルキーウィンドウに対応するTextMeshPro、Imageオブジェクトを配置します。
親オブジェクトのItemに、先程作成したSampleItemDataSetter
をアタッチし、インスペクタから対応する項目をアタッチします。
これで再生してみましょう。以下のようにUIにScriptablObjectで設定した値が表示されていれば成功です。
ScriptableObjectの上手な向き合い方
最後に、個人的にScriptablObjectを作る時の気をつけていることをまとめておきます。
ScriptablObjectの値は更新しないものだけを設定する
ScriptablObjectは基本的に静的なデータを扱うためのものですが、ゲーム中に値が変動するものを扱うのには適していません。レベルごとのパラメータ値など、ゲームプレイ次第で値が変わることが無いようなデータを設定するようにしましょう。
逆に、シーンを跨いでも同じ値でセットしておきたいなどの場合には、ScriptablObjectを使うと整合性の取れたデータを扱うことができるのでオススメです。
ScriptableObjectから欲しいデータを取得するメソッドを入れておく
自作のScriptablObjectは、配列(リスト)形式になることが多いです。
配列(リスト)からデータ取得する場合、取得するためのメソッドをScriptablObject側に仕込んでおくと、設計がキレイになりやすいです。
今回のサンプルだと、以下の部分です。
private void DisplayItemDetails(int id)
{
// IDに該当するアイテムを取得
var item = itemList.GetItemById(id);
if (item != null)
{
itemIconImage.sprite = item.icon;
itemNameText.text = item.itemName;
itemDescriptionText.text = item.description;
itemEffectValueText.text = $"Effect: {item.effectValue}";
}
}
ほかにも、条件に応じてフィルタリングして対応するリストを返すメソッドなど、必要に応じて必要なデータを取得するロジックを仕込んでおくとよいでしょう。
まとめ
ScriptableObjectを使うと、設定値を一律管理できるようになるので、バリエーションを増やすことが容易になります。内容が充実したゲームを作るには必須の機能でしょう。
ぜひ使い方をマスターしてみてください。
それでは素敵なゲーム制作ライフを!
コメント
コメント一覧 (1件)
[…] ScriptablObjectを使って、アイテムや武器などのバリエーションを増やそう! […]