// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 // Unity using UnityEditor; using UnityEngine; namespace AWS.GameKit.Editor.Utils { /// /// A ScriptableObject which survives when the Unity editor restarts or does a Domain Reload. /// /// The object automatically writes itself to disk during OnDisable() and can be loaded with LoadObject(). /// public class PersistentScriptableObject : ScriptableObject where T : PersistentScriptableObject { private string _assetFilePath; private bool _shouldBeSaved; /// /// Load the ScriptableObject from a file on disk. /// /// The path where the ScriptableObject's file will be loaded from and written to. /// The ScriptableObject deserialized from the file. public static T LoadFromDisk(string assetFilePath) { T scriptableObject = AssetDatabase.LoadAssetAtPath(assetFilePath); if (scriptableObject == null) { scriptableObject = CreateInstance(); AssetDatabase.CreateAsset(scriptableObject, assetFilePath); } if (!string.IsNullOrEmpty(assetFilePath)) { scriptableObject._assetFilePath = assetFilePath; scriptableObject._shouldBeSaved = true; } return scriptableObject; } private void WriteToDisk() { // Implementation note: // We persist a clone instead of the original object to ensure the state is non-null when loaded by LoadAssetAtPath() in LoadFromDisk(). // If we persist the object by other means, then LoadAssetAtPath() returns null when LoadFromDisk() is called immediately after script recompilation. _shouldBeSaved = false; T clonedScriptableObject = (T)Instantiate(this); AssetDatabase.CreateAsset(clonedScriptableObject, _assetFilePath); } private void OnDisable() { if (_shouldBeSaved) { WriteToDisk(); } } } }