UnityのScriptableObject【スクリプタブルオブジェクト】とは?初心者向けにResourceDataを作りながら学んでみる

Unity

こんにちは、とまです。

自分が作成しているゲームで、作成する機会があったので、
今回は初心者向けにScriptableObjectについてまとめてみます。

Unityでゲームを作っていると、「食料」「木材」「金属」など、ゲームの中で使うデータをたくさん管理する必要が出てきます。

using UnityEngine;

[CreateAssetMenu(fileName = "ResourceData", menuName = "Game/Resource Data")]
public class ResourceData : ScriptableObject
{
    [Header("基本情報")]
    public string id;
    public string displayName;
    public Sprite icon;
}

最初は「ScriptableObjectって何だろう?」というところから始まったので、今回はこのコードを使いながら、ScriptableObjectについて勉強していきます。

難しい言葉はできるだけ使わず、実際にUnityで触りながら理解できるように説明していきます。

ScriptableObjectって何?

一言でいうと、ScriptableObjectはゲームで使うデータを保存しておくための仕組みです。

例えば、ゲームにこんな資源があるとします。

  • 食料
  • 木材
  • 金属

それぞれに、

  • ID
  • 名前
  • アイコン

などの情報が必要になります。

これをScriptableObjectで作っておくと、

FoodData
WoodData
MetalData

のように、UnityのProjectウィンドウで個別のデータとして管理できます。

イメージとしては、

ResourceData
   ↓
「資源データの設計図」

FoodData
WoodData
MetalData
   ↓
「実際の資源データ」

という感じです。

普通のクラスと何が違うの?

C#には普通のクラスがあります。

例えば、

public class Resource
{
    public string id;
    public string displayName;
}

のようなものです。

これもデータをまとめることはできますが、ScriptableObjectとは少し役割が違います。

ScriptableObjectを使うと、作ったデータをUnityのAssetとして保存できるようになります。

そのため、UnityのProjectウィンドウから、

FoodData.asset
WoodData.asset
MetalData.asset

のようにデータを管理できます。

「コードを書く人」と「ゲームのデータを調整する人」が同じとは限りません!!

ScriptableObjectなら、Inspectorからデータを変更できるので、こうした調整もしやすくなります。

ResourceDataのコードを見てみる

今回作ったコードを少しずつ見ていきます。

[CreateAssetMenu(fileName = "ResourceData", menuName = "Game/Resource Data")]
public class ResourceData : ScriptableObject
{
    [Header("基本情報")]
    public string id;
    public string displayName;
    public Sprite icon;
}

まず、

public class ResourceData : ScriptableObject

の部分です。

ResourceDataというクラスがScriptableObjectを継承しています。

これによって、ResourceDataをScriptableObjectとして扱えるようになります。

「ScriptableObjectを継承することで、Unity上でデータAssetとして使えるようになる」と覚えておけば、最初は十分です。

恐らく、いつも使っているスクリプトは:MonoBehaviourとなっていると思います。
これに関しては、コンポーネントとして使えるオブジェクトだよ、ということです。

CreateAssetMenuって何?

次に、この部分です。

[CreateAssetMenu(fileName = "ResourceData", menuName = "Game/Resource Data")]

これは、UnityのメニューからScriptableObjectのAssetを作れるようにするためのものです。

このコードがあると、Projectウィンドウで右クリックして、

Create
↓
Game
↓
Resource Data

という項目からResourceDataを作れるようになります。

これがかなり便利です。

コードを書き直して毎回データを作るのではなく、Unity上で必要な数だけAssetを作っていけます。

ResourceDataに何を保存するの?

ひとまず、今回のResourceDataには3つの情報を用意しました。

public string id;
public string displayName;
public Sprite icon;

idは、ゲーム内部で資源を識別するための名前です。

例えば、

food
wood
metal

などにします。

displayNameは、プレイヤーに表示する名前です。

食料
木材
金属

といった感じです。

そしてiconは、その資源のアイコン画像です。

つまり、食料なら、

ID          food
表示名      食料
アイコン    食料の画像

というデータを1つのAssetにまとめられます。
今回は、作り始めなのでこんなに少なくて済みますが、どんどん要素を足していくことで、入れる枠も増やすことができます。拡張性に優れているのも、メリットです。

Unityで実際に作ってみる

では、実際にUnityで使ってみます。

まずResourceData.csをUnityプロジェクトに入れます。

その後、Projectウィンドウで右クリックして、

Create
↓
Game
↓
Resource Data

を選択します。

するとResourceDataのAssetが作成されます。

これをFoodDataという名前に変更してみます。

Inspectorを見ると、

基本情報

Id
Display Name
Icon

という項目が表示されます。

ここに、

と設定します。

同じように、

FoodData.asset
WoodData.asset
MetalData.asset

という3つのデータを作ることができます。

ScriptableObjectを使うと何が嬉しいの?

一番嬉しいのは、データと処理を分けられることです。

例えば、

ResourceData
↓
「食料とは何か?」

を管理します。

一方で、

ResourceManager
↓
「食料を増やす」
「食料を減らす」
「現在の食料数を取得する」

といった処理を担当させます。

先ほども記載しましたが、
このように役割を分けておくと、後からゲームを大きくしていくときに管理しやすくなります。

今回のゲームでも、

FoodData
WoodData
MetalData

を作っておけば、新しい資源を追加したくなったときも、Assetを増やしていくことで対応できます。

ScriptableObjectにゲームの現在値を入れるのは注意

ここは少しだけ注意が必要です。

ScriptableObjectはデータを保存するのに便利ですが、ゲーム中に変化するプレイヤーの状態を何でも入れるものではありません。

例えば、

現在の食料 → 35
現在の木材 → 20
現在の金属 → 8

といった「今プレイヤーが何個持っているか」という情報は、ゲームの状態として別に管理するほうが分かりやすいです。

今回のResourceDataなら、

食料とは何か?
木材とは何か?
金属とは何か?

という「資源そのものの定義」を持たせます。

そして、

現在、食料を35個持っている

という情報は、別のゲーム状態管理側で扱います。

この違いを意識しておくと、ScriptableObjectを使うときに迷いにくくなります。

まとめ

今回は、資源データを管理するためにResourceDataというScriptableObjectを作ってみました。

ScriptableObjectについて簡単にまとめると、

  • Unityでゲームのデータを管理するための仕組み
  • データをAssetとして保存できる
  • Inspectorから内容を編集できる
  • 複数のゲームオブジェクトから同じデータを参照できる
  • データとゲームの処理を分けやすい

という特徴があります。

最初は「ScriptableObject」という名前だけ見ると少し難しそうですが、実際に使ってみると、

「ゲームで使うデータを、Unity上で扱いやすく保存しておくもの」

と考えるとかなり分かりやすいと思います。

今回作ったResourceDataも、これからゲームを作っていく中で、食料・木材・金属などの資源を管理するために使っていく予定です。

ゲームを作りながら新しい仕組みを覚えていくと、単純に勉強するよりも「なぜ必要なのか」が分かりやすくて面白いですね。

本日はここまでです!
またお会いしましょう~!

コメント

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