ScriptableObjectって何??
先日TLでScriptableObjectっていうものを聞いて気になってたので調べてみた。
AssetBundle + コルーチン + ScriptableObjectで自由なデータ構造バイナリー作って非同期にサーバーからアセットをロードしてシーケンスにゲームデータとして取り込むって言えばわかりやすいかも。それが簡単にできる。
— alwei (@aizen76) 2014, 7月 21
ツイート引用ごめんなさい。まー結果から言うとよくわからなかったんだけど色々できそうな予感はする。予感だけ。
とりあえず今日知ったことだけまとめとこう。
参考サイト
- ScriptableObject | 公式リファレンス(英語)
- スクリプタブル オブジェクト | 公式リファレンス(日本語)
- 「ScriptableObject を使用する場面は、値の複製をさけることでメモリ消費を節約するときですが」って記述があるね
- [Unity]ScriptableObjectの使い方 | テラシュールウェア
- ScriptableObjectを継承したクラスから.assetファイルを簡単に作るスクリプトを紹介してる
- ScriptableObjectをプレハブとして出力する汎用スクリプト | Gist
- ↑の記事のスクリプト本体
- チーム共通設定に.assetファイルを扱う | 青空の月
- ScriptableObjectが本領発揮するのはやっぱりエディタ拡張っぽいことが書かれてる
- アセットバンドル(Unity Proのみ) | 公式リファレンス
- Pro専用だけど実行時に追加データをダウンロードする機能
- [Unity]Excelでデータを管理してUnity iOS/Androidで使うワークフローをもう少し詳しく(修正版) | テラシュールウェア
- Excel→ScriptableObjectへの変換してるっぽい
- https://github.com/anchan828/unitejapan2014/tree/master/GlobalGameManager | GitHub
- ScriptableObjectを使ってGameManagerを生成してるっぽい。(実行してないので予想)
利用法
ざっと見た感じ、下記の利用方法でメリットがありそう- 特定のGameObjectに属さず、共通で参照されるべきデータを保持する場合
- 例えば、レベルレイアウト、お店の商品、敵ごとのステータス、などなど
- リリース時にあらかじめデータの入っているDBとして使う場合
- これもレベルレイアウトや、商品とか。読み取り専用として扱うもの全般。
- シーンをまたいで保持したい内容
- ゲームスコアとか
- ゲーム中に書き換えることもできるけど毎起動時に初期化される模様(後述)。
- でもこの利用法ならシングルトンなオブジェクトで十分とも思える。
- UnityPro限定だけど、AssetBundleを利用する場合
- レベルレイアウトなどをScriptableObjectを使って.asset化しておき、アセットバンドル機能でダウンロードしたりすれば変換なしで直接利用できるっぽい。
ってことが冒頭のalwei(@aizen76)さんの呟きですね。 - 外部データ(Excelとか)をインポートするときに利用
- そのままレベルデータとして利用したり。これは便利そう。
- エディタ拡張
- やったことないし未知
- 拡張するなら間違いなく使うことになりそう
あと思ったこと
- ハイスコアや所持アイテムなど、ゲーム終了・再開時のための永続化についてはやっぱりPlayerPrefsを使うのが正解っぽい…?
(UnityでDBって何使うの?って会話でScriptableObjectの話がでてきたのでRDBの代わりとしてデータ保存目的で使えることを期待してたので残念)
XMLとかJSONにパースしてPlayerPrefsと組み合わせればできそうだけどなんだかなぁ・・・
とりあえずゲーム内で使ってみた
よくわからんけどどんな動きするか見てみた。新規Project作成
Editorフォルダを作って椿さんのこのスクリプトを配置
https://gist.github.com/tsubaki/5149402
Resourcesフォルダを作り、下記スクリプトを作成
ClickCount.cs
using UnityEngine; using System.Collections; public class ClickCount : ScriptableObject { public int Value; }
Cubeを1つ配置(必要ならDirectionLightも)
下記スクリプトを作成し、Cubeにつける
Cube.cs
using UnityEngine; using System.Collections; public class Cube : MonoBehaviour { private ClickCount clickCount; void Start () { this.clickCount = Resources.Load<ClickCount>("ClickCount"); } void OnGUI() { GUI.Label(new Rect(10, 10, 200, 80), this.clickCount.Value.ToString()); } void OnMouseDown() { ClickCount.Instantiate(this.clickCount); this.clickCount.Value++; } }
Resouces/ClickCount.csを右クリックし、Create ScriptableObjectを押す
ClickCount.assetができてるはず
再生ボタンを押して実行
CubeをクリックするとClickCount.assetのValueがインクリメントされる
Inspectorビューを見てると変化してくのがよくわかる。
しかもこれは再生を止めても保存されてる。
実行中に書き換えたものが.assetに書き込まれて残ってるっぽい。
この動きならハイスコアの保存とかに使えるか?
とも思ったけどWebPlayerとかだと毎回初期化されるみたいね。
↓再生ボタンで実行中に17まで進めて、WebPlayer向けにリリースしたもの。
Hosted by UnityRoom.com
毎回初期化されるのでブラウザをリロードすると17に戻る。
うーん、まだしっくりこないな。
エディタ拡張するようになるとなくてはならない存在になりそうだけど。
今日はここまで。