(:3[kanのメモ帳]スマートフォン用の表示で見る(:3[kanのメモ帳]個人ゲーム開発者kan.kikuchiのメモ的技術ブログ。月木更新でUnity関連がメイン。利点メモリ節約パラメータの比較や管理が容易Unity上で確認、調整がしやすい。他のアセットを設定出来る。公式のマニュアル等を見てみると以下のように書かれています。スクリプトインスタンスから独立した大量の共有データを格納できるクラスです。データを格納するオブジェクトです。言えば、Unityがデータをシリアライズ・デシリアライズしパラメータを格納するための仕組みです。独自のアセットを作成するための仕組みです。シリアライズ機構が扱う形式とも言えます。ScriptableObjectは、Unityによってシリアライズされたデータ群をアセットとして保持する為の仕組みです。色々な書き方がされていますが、自分なりに分かりやすさ重視で簡潔にまとめてみると、ScriptableObjectとは「ゲーム中に変化しないデータをアセットとして作成する仕組み」と言った感じでしょうか。上記の通り、ScriptableObjectはゲーム中に変化しないデータを扱うのに向いています。言い方を変えると静的なデータ、固定データ、定数などの事で、データ量は多くても少なくても有用です。(詳しくは次項の利点にて)一口に変化しないデータと言っても、様々な用途が考えられます。敵キャラの初期ステータスと言った数値データや、UIに表示するテキストデータ、イベントが発生する条件の条件データなどの事です。永続的なセーブデータのような使い方には向いてません。用途はなんとなく分かってもらえたと思いますが、なんでわざわざScriptableObjectを使うの?という話になるかと思います。変数を作ってInspectorで設定したり、JSONにまとめたり等、他のやり方はいくらでもあります。今度はScriptableObjectの利点についてです。以下のように、HPというステータスをもった敵クラスがあったとします。簡略化のため敵の種類は1種類として考えます。今回は分かりやすいように、それぞれ1メモリ、計2メモリ消費してると言い換えてみます。敵(のインスタンス)を大量に作るほど、消費するメモリも増えていきます。10体作れば20メモリ、100体作れば200メモリです。全員同じはずの_initialHPが複数作られ、メモリを消費するのは勿体ないですよね?なので_initialHPをstatic(この場合はconstの方が適切ですが)にしてみます。すると_initialHPは共通の値となり、敵をどれだけ作っても1メモリしか消費しなくなります。10体作っても11メモリ、100体作っても101メモリです。敵がいないタイトル画面やリザルト画面等でも1メモリは常に使われてる事になります。必要ない時はメモリを使わない(ScriptableObjectをロードせず)、という具合にメモリ節約が行えます。変更時の漏れや値のズレによるバグの原因となります。敵の種類やステータスが増えると、それだけ直書きする手間やバグの可能性も増えるため基本的にはやらないほうが得策です。パラメータの比較や管理が容易ScriptableObjectは一つのアセット(ファイル)なので、コピーや差し替えが簡単に行えます。いう事は、ファイルを複数用意する事で、パラメータの比較が容易に行えるという事でもあります。敵キャラに複数のパラメータ(HPや攻撃力、防御力など)があった場合、それをプログラムで直接指定してしまうと、比較する際に毎回書き換える必要がありますが、このパラメータをScriptableObjectにしてしまえば、ファイルを差し替えるだけになります。敵ごとにパラメータのファイルを用意すれば、管理も容易です。Unity上で確認、調整がしやすい。他のアセットを設定出来る。今までの利点はJSON等の他のファイルを使っても同じ話だったりします。次は他のファイル形式と比較した場合のScriptableObjectの利点で、Unity上で確認、調整がしやすいという話です。JSON等のファイルはUnity用のファイル形式ではないため、Unity上では確認しづらいですが、ScriptableObjectはUnityが提供しているファイル形式なので、見やすいですし、Inspector上でそのまま値を変更する事も可能です。boolならチェックボックス、enumならプルダウン等、Componentと同じ感覚で設定が出来る上に、Sprite等をドラック&ドロップして他のアセットを設定する(参照を持つ)事も可能です。余談ですが、Odinというアセットを使うと、さらに確認や調整がしやすく(というよりInspectorが使いやすく)なりますが、これはまた別のお話。詳しくは後述しますが、ScriptableObjectは簡単に作成したり、使ったり出来ます。JSON等の他のファイルだとそのままでは使えないので、ひと手間必要になりますが、ScriptableObjectにはそれがありません。一部の値を変更不可能にしたりと、ちょっとのプログラムで好きなように機能や表示を変えられます。ロード時間が短く、メモリ使用量も軽減これはJSONと比較してなんですが、ロード時間を短くし、メモリ使用量も軽減する事が出来ます。作成方法さて、利点が分かった所で次はScriptableobjectの作成方法です。クラスの作成まずはScriptableobjectを継承したクラスを作成し、そのクラスに設定したいデータの変数を記述します。以下のようにprivateな変数にSerializeFieldを付けて、getterとsetterを別途用意する方が安全です。setterは後述する「プログラムから作成」の時に使います。各敵のステータスをまとめた構造体またはクラスを作ってListで設定した方が何かと便利です。各項目の名前が、そのstringに設定したものになって分かりやすいのでオススメです。false;次はScriptableobjectの実体、つまりファイルの作成方法ですが、これには大きく分けて二つの方法があります。メニューから作成1つ目がScriptableobjectを継承したクラスにCreateAssetMenuという属性を付ける方法です。これだけでProjectのCreateに作成用のメニューが追加されます。{/*略*/}また、CreateAssetMenuはfileNameで作成時のファイル名を、menuNameでメニューの表示名を、orderで表示順(数字が低い方が上)を指定する事が出来ます。{/*略*/}なお、メニューから作成した場合、データは手動で設定する感じになります。プログラム(Excel)から作成2つ目がプログラムから作成する方法で、データ自体もプログラムで設定したい場合に使います。やり方はMenuItemを付けたメソッド内で、データを設定したScriptableObjectを書き出すだけです。}}上記の例ではデータは直接記述していますが、何かしらの計算をして設定したり、csv等のファイルを読み込んでその値を設定するなんて事も、もちろん可能です。説明が長くなるので今回は割愛します。作り方も分かったので後は使い方ですが、これは至ってシンプルです。他のアセットと同様にResources.Load等でロードして、データを参照(取得)するだけ。Scriptableobjectの欠点や、使用の際の注意点やハマり所についての話です。用途の項目でも説明した通り、Scriptableobjectは実機上だとゲーム終了時に全データが初期値に戻ってしまいます。セーブデータのような可変するデータには向いていません。逆にエディタ上では値を変更しても戻りません。実際のゲームでは変更しないが、エディタ上で調整したい場合にも使いやすいです。変更があった事を記録しないと元に戻るので注意が必要です。(Inspectorから変更した場合は問題ない。警告が表示され、作成したファイルのScriptの欄がNoneになってしまいます。素直にクラス名とファイル名は同じにしましょう。データ量が多いとInspectorの表示が重くなる設定されているデータが数千〜数万件を越えてくると、Inspectorでの表示が重くなり、最悪エディタ自体を強制終了しないといけなくなります。いうデータはエディタ上で選択しない、JSON等の違う形式を使うという回避方法もありますが、そもそもそれだけのデータを一つにまとめてしまうと、ロードに時間がかかったり、大量にメモリを消費してしまったりするので、データを小分けにする事をオススメします。データサイズは圧縮したJSONの方がちょっと軽いロード時間やメモリ使用量的にはJSONよりScriptableobjectの方が有利という話をしましたが、データサイズ的にはは圧縮したJSONの方が軽くなるっぽいです。してもデータサイズをもっと小さくしたいという場合には、JSONを使うという選択肢も考えてみましょう。おわりに以上で説明は終わりですが、結構便利かつ簡単に使えるという事が分かってもらえたでしょうか。ScriptableObjectは名前からだと用途が分かりにくい上に、代替手段が色々とあるため、あまり目立った存在ではありませんが、使ったことがない方は試してみる事をオススメします。はてなブログPro個人ゲーム開発者。ω、)_新作は札束風呂VRや神巫女。Policy広告はてなブログをはじめよう!kan_kikuchiさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。