はじめに
罠でも何でもなく、私がScriptable Objectsの仕様を理解していない、使い方も間違えていました。
シーン間の一時的なデータのやりとりや、一時的なデータ保管庫としての利用が適切な使い方であって、セーブデータストアとして使うものではないようです。
エディタ上で保存できたので、データ入れればメモリ経由で永続保存する、超優れたデータストア!くらいな認識でした。readオンリーでマスタデータとして使うのが仕様なようです。わかりづらいんだよ。
対処方法
今制作しているゲームとは別の推理ゲームモック制作時に何となく気がついていたのですが、EditorUtility.SetDirtyとAssetDatabase.SaveAssets()で保存できて、
実機でも正常に動いていたので(エディター上での変更がプロジェクトに反映されてただけでした)、まぁ、これでよいかと放置していました。分からないものを分からないまま放置したあげく、遊んでくれる方のデータを簡単に失う可能性があるような状態にはしたくないですね。
read json->Scriptable Objects->write jsonで対応させようと思います。
ScriptableObjectは、Unityでのデータ管理や再利用性を高めるために設計された特殊なデータオブジェクトです。主にデータの保存や共有を簡単に行うために使われ、MonoBehaviourとは異なり、ゲームオブジェクトにアタッチされる必要はありません。これにより、プロジェクト内で再利用可能なデータを効率的に管理できるようになります。
ScriptableObjectの目的
- データの管理と分離
- ScriptableObjectは、ゲームの設定データやアイテム、キャラクターのステータスなどのデータを格納するために使います。これにより、コードとデータが分離され、コードの保守性が向上します。
- 複数のオブジェクト間でのデータ共有
- ScriptableObjectは複数のシーンやオブジェクト間で簡単に共有することができます。たとえば、ゲーム内の設定データや共有するスコアなどのデータを保持するのに適しています。
- メモリの効率化
- ScriptableObjectはメモリの管理に優れ、同じデータを使い回す場合に特に便利です。インスタンスごとにデータを複製するのではなく、データ自体を参照するため、パフォーマンスが向上します。
- インスペクターで編集可能
- Unityのインスペクターを通して、ScriptableObjectのデータを簡単に編集できます。デザイナーや他の開発者がスクリプトを触らずに、データのみを調整できるようになります。
ScriptableObjectの利点
- 再利用性が高い
- 一度作成したScriptableObjectは複数のプレハブやシーン、スクリプトで簡単に再利用可能です。
- データの一元管理
- ゲーム内のアイテムやキャラクターのデータなどを1つのScriptableObjectにまとめて管理でき、変更を加えた場合、すべての参照先に反映されます。
- 軽量なオブジェクト
- ScriptableObjectは軽量で、ゲームオブジェクトやコンポーネントのように大量のオーバーヘッドが発生しません。これにより、パフォーマンスの向上が期待できます。
- 状態を持たないデータの管理に最適
- ScriptableObjectはゲームプレイ中の一時的なデータではなく、データ自体の定義や共有に向いています。例えば、アイテムやステータス、設定などのデータを保存するのに最適です。
ScriptableObjectを使うべき場合
- アイテムやスキル、キャラクターデータの管理
- RPGやアクションゲームにおけるアイテムやスキルのステータスをScriptableObjectで管理することで、複数のオブジェクトで共有しやすくなります。
- ゲーム設定の管理
- ゲームの設定(音量、難易度、グラフィック設定など)をScriptableObjectで管理し、メインメニューやゲーム中で共有・参照できます。
- 複数のオブジェクトでデータを共有する必要がある場合
- 例えば、複数のエネミーが同じデータ(攻撃力や体力など)を参照する場合、ScriptableObjectを使ってこれらのデータを共有することで、メンテナンスが楽になります。
ScriptableObjectは、データを効率的に管理し、再利用可能にする強力なツールです。特に、ゲームオブジェクトにアタッチする必要のないデータや、複数のオブジェクトで共有するデータを管理する際に便利です。データの分離と管理を行いたい場合に活用することで、プロジェクトのスケーラビリティと保守性が大幅に向上します。
おわりに
Playmakerにも対応しているEasySaveアセットを所有しているので、最終的にそれを使えばデータのロード、セーブ問題は解決するのですが、作る過程で理解したいことも多かったので、今回結果Scriptable Objects特徴に少しだけ触れられてよかったです。
以下動画解説が分かりやすかったです。
直近で制作していて、だんだんと趣旨からずれてきたなと思います。なのでまず、既存アセットも多様して、さくっと作りたいものを形にしてから、手法を考えていきたいと思います。あまり考えて、凝っていくと、それに囚われて、作るモチベーションがどんどん落ちています。週末に仕事みたいなことはしたくないですね。
うまくScriptable Objectsの構造体をシリアライズ、デシリアライズして呼び出し、保存ができるようになりました。
最初MonoBehaviourで実装してオブジェクトに貼り付けてPlaymakerからCall Methodしたのですが、処理タイミングのせいかうまく動かなくなってしまい、EasySaveにしようかな…と思い始めて、その前にカスタムアクションに移動したらWindows,Android共に想定どおりに動くようになりました。

これでマスタデータはScriptable Object、シーン間やオブジェクト間FSMの動的データの参照はScriptable Objectから、動的データはjsonで保存できるようになりました。
Scriptable Object, yaml, csv, xml マスタデータ、設定値、ReadOnly
PlayerPrefab 現在のプレイヤーデータ R/W
Json マスタデータ、プレイヤーデータ R/W セーブスロット、バックアップ、テンポラリ 、PlayerPrefabとJsonのデータでチェックサム比較チート対策とか。

