ScriptableObjectのデータ保存


今回のお仕事で管理画面での設定データをScriptableObjectに保存。今回はResourcesフォルダに保存してシングルトンとしてデータを書き換えられるようにした。ScriptableObjectはUnityEditor上では再生時に値を書き換えたりしても値が戻らないけど、書き出した時は話が別。
(UnityEditor上でもビルドとかすると値が戻ったりするけど)
そこで、Jsonで保存/リストアができるように。

ScriptableObjectからへのエンコードにはJsonUtilityを使用。JsonUtilityって外部APIから持ってきたJsonを扱うには変な感じだなと思ってたけど、UnityでのSerializableなオブジェクトを扱う用のものなんですね。

using UnityEngine;
using UnityEngine.UI;

public class Main : MonoBehaviour {
	/// <summary>
	/// 設定ファイルで設定したenemyNumの表示用。
	/// </summary>
	[SerializeField]
	Text enemyNumTxt;

	/// <summary>
	/// Awake.
	/// </summary>
	void Awake() {
		++Settings.Instance.enemyNum;
		enemyNumTxt.text = Settings.Instance.enemyNum.ToString();
		Settings.Instance.Save();
	}
}
using UnityEngine;

/// <summary>
/// クラスメイト同名のアセットからScriptableObjectをシングルトンとして扱う。
/// </summary>
public abstract class SingletonScriptableObjectFromResources<T> : ScriptableObject where T : ScriptableObject {
	/// <summary>
	/// シングルトン。
	/// </summary>
	static T instance = null;
	public static T Instance {
		get {
			if (!instance)
				instance = Resources.Load<T>(typeof(T).Name);

			return instance;
		}
	}
}
using System;
using System.IO;
using UnityEngine;

[CreateAssetMenu(menuName = "Settings/Create Settings", fileName = "Settings")]
public class Settings : SingletonScriptableObjectFromResources<Settings> {
	/// <summary>
	/// Jsonを保存するパス。
	/// </summary>
	public static string JsonPath {
		get {
			return Application.persistentDataPath + "/" + "Settings.json";
		}
	}

	/// <summary>
	/// 敵の数。
	/// </summary>
	public int enemyNum;

	/// <summary>
	/// 制限時間。
	/// </summary>
	public float timeLimit;

	/// <summary>
	/// ステージにあるアイテム。
	/// </summary>
	public Item[] item;

	/// <summary>
	/// OnEnable.
	/// </summary>
	public void OnEnable() {
		this.Restore();
	}

	/// <summary>
	/// データを復元。
	/// </summary>
	public void Restore() {
#if !UNITY_EDITOR
		if (File.Exists(Settings.JsonPath)) {
			string json = File.ReadAllText(Settings.JsonPath);

			try {
				JsonUtility.FromJsonOverwrite(json, this);
			}
			catch (Exception e) {
				throw e;
			}
		}
#endif
	}

	/// <summary>
	/// 保存。
	/// </summary>
	public void Save() {
		string json = JsonUtility.ToJson(this);

		StreamWriter writer = new StreamWriter(Settings.JsonPath);

		try {
			writer.Write(json);
			writer.Flush();
		}
		catch (Exception e) {
			throw e;
		}
		finally {
			if (writer != null)
				writer.Dispose();
		}
	}

	/// <summary>
	/// アイテムデータ。
	/// </summary>
	[System.Serializable]
	public class Item {
		public int id;

		public Vector3 pos;
	}
}

18.04.10 追記) UnityEditor上で編集すると値が戻ってしまうので、UnityEditor上ではJsonから復元しないように修正

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です