# Example Script

This script saves the player's transform values in a save state and a string in player settings. This script is used for the demo scene.

```csharp
using Esper.ESave.SavableObjects;
using UnityEngine;

namespace Esper.ESave.Examples
{
    /// <summary>
    /// An example script that saves and loads the player's position and rotation.
    /// </summary>
    public class SaveLoadExample : MonoBehaviour
    {
        /// <summary>
        /// The ID used for saving the player transform.
        /// </summary>
        private const string playerTransformID = "PlayerTransform";

        /// <summary>
        /// The ID used for saving a random setting.
        /// </summary>
        private const string mySettingID = "MySetting";

        /// <summary>
        /// The player transform.
        /// </summary>
        [SerializeField]
        private Transform playerTransform;

        /// <summary>
        /// Creates a save state.
        /// </summary>
        public void CreateSave()
        {
            // Create a save state with the ID 0 if it doesn't exist
            // Passing an ID parameter is not necessary, as a save state will still be created with the first
            // available ID
            ESave.CreateSave(0);
        }

        /// <summary>
        /// Saves the data. Only the player position is saved.
        /// </summary>
        public void Save()
        {
            // This method is recommended as it works no matter which multithread mode is set
            // If multithread mode is set to disabled, using OnComplete's will not be necessary

            // Ensure there's an active save state (only the active save can be edited)
            if (SaveState.active != null)
            {
                // Save the player transform (use the ToSavable extension because the Transform class itself is not savable)
                SaveState.active.AddData(playerTransformID, playerTransform.ToSavable()).OnComplete(data =>
                {
                    // This method confirms all changes made to a save state
                    ESave.Save(0);
                });
            }
            else
            {
                ESaveLogger.LogWarning("Load the save first!.");
            }

            // Saving a value to player settings
            var settings = ESave.GetPlayerSettings();

            settings.AddData(mySettingID, "I am data!").OnComplete(result =>
            {
                Debug.Log("Saved a setting to player settings.");
            });

            // The commented method below will only work if multithread method is set to disabled
            //if (SaveState.active != null)
            //{
            //    SaveState.active.AddData(playerTransformID, playerTransform.ToSavable());
            //    ESave.Save(0);
            //}
            //else
            //{
            //    ESaveLogger.LogWarning("Load the save first!.");
            //}

            //var settings = ESave.GetPlayerSettings();
            //settings.AddData(mySettingID, "I am data!");
            //Debug.Log("Saved a setting to player settings.");
        }

        /// <summary>
        /// Loads the data. This just loads the player position and sets it.
        /// </summary>
        public void Load()
        {
            // Load the save state with the ID 0 if it exists
            ESave.Load(0).OnComplete(saveState =>
            {
                // Set the position data if it exists
                if (saveState != null && saveState.HasData(playerTransformID))
                {
                    // Get the saved data
                    saveState.GetData<SavableTransform>(playerTransformID).OnComplete(result =>
                    {
                        // Since character controller is used, it needs to be disabled before setting the position
                        var characterController = playerTransform.GetComponent<CharacterController>();
                        characterController.enabled = false;

                        // Set the position and rotation
                        playerTransform.SetPositionAndRotation(result.Position, result.Rotation);

                        // Now we can reenable the character controller
                        characterController.enabled = true;
                    });
                }
            });

            // Loading a value from player settings
            var settings = ESave.GetPlayerSettings();

            if (settings.HasData(mySettingID))
            {
                settings.GetData<string>(mySettingID).OnComplete(result =>
                {
                    Debug.Log($"Loaded from player settings: {result}");
                });
            }

            // The commented method below will only work if multithread method is set to disabled
            //var saveState = ESave.Load(0).Result;

            //if (saveState != null && saveState.HasData(playerTransformID))
            //{
            //    var data = saveState.GetData<SavableTransform>(playerTransformID).Result;
            //    var characterController = playerTransform.GetComponent<CharacterController>();
            //    characterController.enabled = false;
            //    playerTransform.SetPositionAndRotation(data.Position, data.Rotation);
            //    characterController.enabled = true;
            //}

            //var settings = ESave.GetPlayerSettings();
            //Debug.Log(settings.GetData<string>(mySettingID).Result);
        }

        /// <summary>
        /// Deletes the save.
        /// </summary>
        public void DeleteSave()
        {
            // Delete the save state with the ID 0 if it exists
            ESave.DeleteSave(0);

            // Unloading the active save state is optional
            // Active save state explanation: the active save state is a copy of the last loaded save state. The
            // purpose of it is so that when the player is playing through the game, the active save state (the
            // copy) is the one being updated instead of the original until ESave.Save is called. This allows
            // the original to be loaded once again without any edits made to it if ESave.Save was not called.
            ESave.Unload();
        }
    }
}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://espergames.gitbook.io/esave/esave-pro/scripting/saving-and-loading/example-script.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
