本記事は、サムザップ #1 AdventCalendar 2020の12/17の記事です。
#はじめに
株式会社サムザップでUnityエンジニアをしている佐藤です。
主に新規開発をしています!
↑
とここまでは去年のアドベントカレンダーと同じ出だしでスタートしました。
実は私、去年から今までずっと同じプロジェクトで新規開発をしていました。リリースはまだもうちょい先なので、大々的にこれやった!みたいなことは言い出しづらいんですが、実績もないし、ただまあ去年から引き続きゲーム開発と環境の整備をしています。
というわけで今回は今のプロジェクトでやっているScriptableObject活用実例を紹介してみようと思います。
去年よりは、もうちょっと具体的なことが書けるな、やったね!
#ScriptableObjectとは
詳細は割愛しますが、
ScriptableObject は、クラスインスタンスとは無関係に、大量のデータを保存するために使用できるデータコンテナです。
という公式リファレンスの文言がすべてを言い表していると感じます。
- メモリ内にデータのコピーが一回ですみ、すべてのプレハブから参照を使ってアクセスできる。
- エディター上では編集中、実行中にデータの保存をすることができる。
- ビルドされたアプリのセーブデータ保存には向かない。
この辺りが特徴といえるかもしれません。
Unity Pro TipsでもScriptableObject活用方法を紹介しています。
ゲーム構築を劇的にスマートにするScriptable Objectの3つの活用方法例
というわけでここから先は私がScriptableObjectをどのように活用しているのかの実例になります。
#デバッグデータでの利用
実際の開発で配信されるマスターデータとの結合までにタイムラグがあることはよくあります。
なので先にアプリ側で使用するデータ構造を定義し、ScriptableObject側にデータを設定して利用しています。
こういう場合、jsonファイルを読み込むという方法もあると思います。
私は以下の理由によりScriptableObjectにしました。
- Unity Editor上で編集、即時反映をさせたい
- データ編集作業もなるべくUnity Editor上で完結させたい
「即時反映」はScriptableObjectを利用する上で、特にアドバンテージのある部分だと思います。
#ゲームで利用する設定データとしての利用
私のプロジェクトではなるべくエンジニア以外の人たちにもUnityを触ってもらっています。
背景やキャラクター、エフェクト、技の演出...
これらはクリエイターさん手動でゲームへの組み込みを行ってもらっています。
そういった時に、例えばですが
- カメラに対する背景の位置
- エフェクトの発生場所
というデータをどこに設定するかという問題が出てきます。
プランナーさんは割とスプレッドシートからのマスターデータで解決したいという要望があるのですが、
クリエイターさんにとっては馴染みの薄いものだと思います。
なのでクリエイターさんがメインで設定するものは、ScriptableObjectを利用することにしました。
- 背景の設定データ
- キャラクターの設定データ
- エフェクトの設定データ
このようなデータはクリエイターさんがUnityに組み込む際に、
一緒にデータを設定してもらうことで、クリエイターさんのみで作業が完結するようにしています。
#Editor拡張を用いた設定データの編集
とはいえ、ScriptableObjectってそのままだと、あまり見やすくありません。
特にデータが大量になったときの編集効率や一覧性は、そのままだと段々辛くなってきます。
クリエイターさんのみで作業が完結することを目指すと設定項目は多岐にわたってきます。
一例としてエフェクトを挙げます。
種別、タイプ、用途、描画位置、発動位置、発生位置、発生サイズ・・・・。
エフェクトは種類も多いです。
これらを踏まえてエフェクトはEditor拡張を用いた編集をしてもらっています。
まずエフェクトごとに用途を定めて、設定項目を決めました。
実際のゲームではこの設定項目に合わせて処理を行うようにしました。
エディター拡張によるデータ設定を行うことで、以下のようなメリットもありました。
- 設定項目を日本語で表示することができる
- エンジニアだけがいじりたい設定を隠蔽できる(Editor拡張に表示させない)。
- データが大量になった時に備えて、ソート機能や絞り込み機能も準備できる。
というわけで煩雑で、大量のデータを扱う際はEditor拡張を用いた方が効率がよくなると思います。
#デバッグ機能としての利用
先ほどScriptableObjectは即時反映できるのがアドバンテージと言いました。
それは特にデバッグ機能として利用することで、非常に使いやすくなると思います。
ゲーム内容に関わるので、具体的に言いづらいですが
例えば各キャラクターにそれぞれデバッグ用のScriptableObjectを参照させます。
すると、ScriptableObjectの値を変更することで、各キャラクターの状態を即時変更することが可能です。
Editorであれば、インスペクターからデータをそのまま変更すればよいですし、
実機であっても、ScriptableObjectをコントロールするデバッグコントローラーを1つ用意するだけで、
あら不思議。複雑な依存関係をすっ飛ばしてキャラクターを制御できたりします。
今のプロジェクトではこの仕組みを意識することで、かなり細かい制御をワンタッチで行っています。
#おわりに
ScriptableObjectを使用することで、開発の効率化を行うことができました。
最初に今のプロジェクトに関わることになった時に、
- スクリプトで解決する部分を少なくする
- 色々な職種の人にUnityを触ってもらう
ということを意識して設計を行いました。
その設計を実現するにあたり、ScriptableObjectは非常に有用でした。
明日は@mmm_hiroさんの記事です。